Commit 94247db42f5e230f84031f2dd3d294b305889148
1 parent
2372de54
Exists in
master
and in
1 other branch
retab spacing Question
Showing
1 changed file
with
211 additions
and
211 deletions
Show diff stats
app/models/question.rb
| ... | ... | @@ -36,7 +36,7 @@ class Question < ActiveRecord::Base |
| 36 | 36 | def create_choices_from_ideas |
| 37 | 37 | if ideas && ideas.any? |
| 38 | 38 | ideas.each do |idea| |
| 39 | - choices.create!(:creator => self.creator, :active => true, :data => idea.squish.strip) | |
| 39 | + choices.create!(:creator => self.creator, :active => true, :data => idea.squish.strip) | |
| 40 | 40 | end |
| 41 | 41 | end |
| 42 | 42 | end |
| ... | ... | @@ -48,27 +48,27 @@ class Question < ActiveRecord::Base |
| 48 | 48 | def choose_prompt(options = {}) |
| 49 | 49 | |
| 50 | 50 | # if there is one or fewer active choices, we won't be able to find a prompt |
| 51 | - if self.choices.size - self.inactive_choices_count <= 1 | |
| 52 | - raise RuntimeError, "More than one choice needs to be active" | |
| 53 | - end | |
| 54 | - | |
| 55 | - if self.uses_catchup? || options[:algorithm] == "catchup" | |
| 56 | - logger.info("Question #{self.id} is using catchup algorithm!") | |
| 57 | - next_prompt = self.pop_prompt_queue | |
| 58 | - if next_prompt.nil? | |
| 59 | - logger.info("DEBUG Catchup prompt cache miss! Nothing in prompt_queue") | |
| 60 | - next_prompt = self.catchup_choose_prompt | |
| 61 | - record_prompt_cache_miss | |
| 62 | - else | |
| 63 | - record_prompt_cache_hit | |
| 64 | - end | |
| 65 | - self.send_later :add_prompt_to_queue | |
| 66 | - return next_prompt | |
| 67 | - else | |
| 68 | - #Standard choose prompt at random | |
| 51 | + if self.choices.size - self.inactive_choices_count <= 1 | |
| 52 | + raise RuntimeError, "More than one choice needs to be active" | |
| 53 | + end | |
| 54 | + | |
| 55 | + if self.uses_catchup? || options[:algorithm] == "catchup" | |
| 56 | + logger.info("Question #{self.id} is using catchup algorithm!") | |
| 57 | + next_prompt = self.pop_prompt_queue | |
| 58 | + if next_prompt.nil? | |
| 59 | + logger.info("DEBUG Catchup prompt cache miss! Nothing in prompt_queue") | |
| 60 | + next_prompt = self.catchup_choose_prompt | |
| 61 | + record_prompt_cache_miss | |
| 62 | + else | |
| 63 | + record_prompt_cache_hit | |
| 64 | + end | |
| 65 | + self.send_later :add_prompt_to_queue | |
| 66 | + return next_prompt | |
| 67 | + else | |
| 68 | + #Standard choose prompt at random | |
| 69 | 69 | next_prompt = self.picked_prompt |
| 70 | - return next_prompt | |
| 71 | - end | |
| 70 | + return next_prompt | |
| 71 | + end | |
| 72 | 72 | |
| 73 | 73 | end |
| 74 | 74 | |
| ... | ... | @@ -92,16 +92,16 @@ class Question < ActiveRecord::Base |
| 92 | 92 | prompt = nil |
| 93 | 93 | |
| 94 | 94 | until prompt && prompt.active? |
| 95 | - target = rand | |
| 96 | - left_choice_id = right_choice_id = nil | |
| 97 | - | |
| 98 | - weighted.each do |item, weight| | |
| 99 | - if target <= weight | |
| 100 | - left_choice_id, right_choice_id = item.split(", ") | |
| 101 | - break | |
| 102 | - end | |
| 103 | - target -= weight | |
| 104 | - end | |
| 95 | + target = rand | |
| 96 | + left_choice_id = right_choice_id = nil | |
| 97 | + | |
| 98 | + weighted.each do |item, weight| | |
| 99 | + if target <= weight | |
| 100 | + left_choice_id, right_choice_id = item.split(", ") | |
| 101 | + break | |
| 102 | + end | |
| 103 | + target -= weight | |
| 104 | + end | |
| 105 | 105 | prompt = prompts.find_or_create_by_left_choice_id_and_right_choice_id(left_choice_id, right_choice_id, :include => [{ :left_choice => :item }, { :right_choice => :item }]) |
| 106 | 106 | end |
| 107 | 107 | # check if prompt has two active choices here, maybe we can set this on the prompt level too? |
| ... | ... | @@ -116,24 +116,24 @@ class Question < ActiveRecord::Base |
| 116 | 116 | sum = 0.0 |
| 117 | 117 | |
| 118 | 118 | prompts.find_each(:select => 'votes_count, left_choice_id, right_choice_id') do |p| |
| 119 | - value = [(1.0/ (p.votes.size + 1).to_f).to_f, throttle_min].min | |
| 119 | + value = [(1.0/ (p.votes.size + 1).to_f).to_f, throttle_min].min | |
| 120 | 120 | weights["#{p.left_choice_id}, #{p.right_choice_id}"] = value |
| 121 | - sum += value | |
| 121 | + sum += value | |
| 122 | 122 | end |
| 123 | 123 | |
| 124 | 124 | # This will not run once all prompts have been generated, |
| 125 | - # but it prevents us from having to pregenerate all possible prompts | |
| 125 | + # but it prevents us from having to pregenerate all possible prompts | |
| 126 | 126 | if weights.size < choices.size ** 2 - choices.size |
| 127 | 127 | choices.each do |l| |
| 128 | - choices.each do |r| | |
| 129 | - if l.id == r.id | |
| 130 | - next | |
| 131 | - end | |
| 132 | - if !weights.has_key?("#{l.id}, #{r.id}") | |
| 128 | + choices.each do |r| | |
| 129 | + if l.id == r.id | |
| 130 | + next | |
| 131 | + end | |
| 132 | + if !weights.has_key?("#{l.id}, #{r.id}") | |
| 133 | 133 | weights["#{l.id}, #{r.id}"] = throttle_min |
| 134 | - sum+=throttle_min | |
| 135 | - end | |
| 136 | - end | |
| 134 | + sum+=throttle_min | |
| 135 | + end | |
| 136 | + end | |
| 137 | 137 | end |
| 138 | 138 | end |
| 139 | 139 | |
| ... | ... | @@ -160,37 +160,37 @@ class Question < ActiveRecord::Base |
| 160 | 160 | @prompt = choose_prompt(:algorithm => params[:algorithm]) |
| 161 | 161 | @appearance = current_user.record_appearance(visitor, @prompt) |
| 162 | 162 | else |
| 163 | - #only display a new prompt and new appearance if the old prompt has not been voted on | |
| 164 | - @appearance = last_appearance | |
| 163 | + #only display a new prompt and new appearance if the old prompt has not been voted on | |
| 164 | + @appearance = last_appearance | |
| 165 | 165 | @prompt= @appearance.prompt |
| 166 | 166 | end |
| 167 | 167 | |
| 168 | 168 | if params[:future_prompts] |
| 169 | - num_future = params[:future_prompts][:number].to_i rescue 1 | |
| 170 | - num_future.times do |number| | |
| 171 | - offset = number + 1 | |
| 169 | + num_future = params[:future_prompts][:number].to_i rescue 1 | |
| 170 | + num_future.times do |number| | |
| 171 | + offset = number + 1 | |
| 172 | 172 | last_appearance = get_first_unanswered_appearance(visitor, offset) |
| 173 | 173 | if last_appearance.nil? |
| 174 | 174 | @future_prompt = choose_prompt(:algorithm => params[:algorithm]) |
| 175 | 175 | @future_appearance = current_user.record_appearance(visitor, @future_prompt) |
| 176 | - else | |
| 177 | - @future_appearance = last_appearance | |
| 176 | + else | |
| 177 | + @future_appearance = last_appearance | |
| 178 | 178 | @future_prompt= @future_appearance.prompt |
| 179 | - end | |
| 180 | - | |
| 179 | + end | |
| 180 | + | |
| 181 | 181 | result.merge!({"future_appearance_id_#{offset}".to_sym => @future_appearance.lookup}) |
| 182 | 182 | result.merge!({"future_prompt_id_#{offset}".to_sym => @future_prompt.id}) |
| 183 | 183 | |
| 184 | - ["left", "right"].each do |side| | |
| 185 | - ["text", "id"].each do |param| | |
| 186 | - choice = (side == "left") ? @future_prompt.left_choice : @future_prompt.right_choice | |
| 187 | - param_val = (param == "text") ? choice.data : choice.id | |
| 184 | + ["left", "right"].each do |side| | |
| 185 | + ["text", "id"].each do |param| | |
| 186 | + choice = (side == "left") ? @future_prompt.left_choice : @future_prompt.right_choice | |
| 187 | + param_val = (param == "text") ? choice.data : choice.id | |
| 188 | 188 | |
| 189 | 189 | result.merge!({"future_#{side}_choice_#{param}_#{offset}".to_sym => param_val}) |
| 190 | - end | |
| 191 | - end | |
| 192 | - | |
| 193 | - end | |
| 190 | + end | |
| 191 | + end | |
| 192 | + | |
| 193 | + end | |
| 194 | 194 | |
| 195 | 195 | end |
| 196 | 196 | |
| ... | ... | @@ -219,7 +219,7 @@ class Question < ActiveRecord::Base |
| 219 | 219 | if votes_by_visitors.size > 0 |
| 220 | 220 | average = votes_by_visitors.inject(0){|total, (k,v)| total = total + v}.to_f / votes_by_visitors.size.to_f |
| 221 | 221 | else |
| 222 | - average = 0.0 | |
| 222 | + average = 0.0 | |
| 223 | 223 | end |
| 224 | 224 | |
| 225 | 225 | result.merge!(:average_votes => average.round) # round to 2 decimals |
| ... | ... | @@ -232,22 +232,22 @@ class Question < ActiveRecord::Base |
| 232 | 232 | #passing precomputed sum saves us a traversal through the array |
| 233 | 233 | def normalize!(weighted, sum=nil) |
| 234 | 234 | if weighted.instance_of?(Hash) |
| 235 | - if sum.nil? | |
| 236 | - sum = weighted.inject(0) do |sum, item_and_weight| | |
| 237 | - sum += item_and_weight[1] | |
| 238 | - end | |
| 239 | - sum = sum.to_f | |
| 240 | - end | |
| 241 | - weighted.each do |item, weight| | |
| 242 | - weighted[item] = weight/sum | |
| 243 | - weighted[item] = 0.0 unless weighted[item].finite? | |
| 244 | - end | |
| 235 | + if sum.nil? | |
| 236 | + sum = weighted.inject(0) do |sum, item_and_weight| | |
| 237 | + sum += item_and_weight[1] | |
| 238 | + end | |
| 239 | + sum = sum.to_f | |
| 240 | + end | |
| 241 | + weighted.each do |item, weight| | |
| 242 | + weighted[item] = weight/sum | |
| 243 | + weighted[item] = 0.0 unless weighted[item].finite? | |
| 244 | + end | |
| 245 | 245 | elsif weighted.instance_of?(Array) |
| 246 | - sum = weighted.inject(0) {|sum, item| sum += item} if sum.nil? | |
| 247 | - weighted.each_with_index do |item, i| | |
| 248 | - weighted[i] = item/sum | |
| 249 | - weighted[i] = 0.0 unless weighted[i].finite? | |
| 250 | - end | |
| 246 | + sum = weighted.inject(0) {|sum, item| sum += item} if sum.nil? | |
| 247 | + weighted.each_with_index do |item, i| | |
| 248 | + weighted[i] = item/sum | |
| 249 | + weighted[i] = 0.0 unless weighted[i].finite? | |
| 250 | + end | |
| 251 | 251 | |
| 252 | 252 | end |
| 253 | 253 | end |
| ... | ... | @@ -266,8 +266,8 @@ class Question < ActiveRecord::Base |
| 266 | 266 | |
| 267 | 267 | # Initial probabilities chosen at random |
| 268 | 268 | the_choices.size.times do |
| 269 | - probs << rand | |
| 270 | - prev_probs << rand | |
| 269 | + probs << rand | |
| 270 | + prev_probs << rand | |
| 271 | 271 | end |
| 272 | 272 | |
| 273 | 273 | t=0 |
| ... | ... | @@ -287,13 +287,13 @@ class Question < ActiveRecord::Base |
| 287 | 287 | |
| 288 | 288 | denominator = 0.0 |
| 289 | 289 | the_choices.each_with_index do |c, index| |
| 290 | - if(index == s) | |
| 291 | - next | |
| 292 | - end | |
| 290 | + if(index == s) | |
| 291 | + next | |
| 292 | + end | |
| 293 | 293 | |
| 294 | - wins_and_losses = the_prompts["#{choice.id}, #{c.id}"].votes.size + the_prompts["#{c.id}, #{choice.id}"].votes.size | |
| 294 | + wins_and_losses = the_prompts["#{choice.id}, #{c.id}"].votes.size + the_prompts["#{c.id}, #{choice.id}"].votes.size | |
| 295 | 295 | |
| 296 | - denominator+= (wins_and_losses).to_f / (prev_probs[s] + prev_probs[index]) | |
| 296 | + denominator+= (wins_and_losses).to_f / (prev_probs[s] + prev_probs[index]) | |
| 297 | 297 | end |
| 298 | 298 | probs[s] = numerator / denominator |
| 299 | 299 | # avoid divide by zero NaN |
| ... | ... | @@ -303,25 +303,25 @@ class Question < ActiveRecord::Base |
| 303 | 303 | |
| 304 | 304 | difference = 0 |
| 305 | 305 | probs.each_with_index do |curr, index| |
| 306 | - difference += (curr - prev_probs[index]).abs | |
| 306 | + difference += (curr - prev_probs[index]).abs | |
| 307 | 307 | end |
| 308 | 308 | puts difference |
| 309 | 309 | end |
| 310 | 310 | |
| 311 | 311 | probs_hash = {} |
| 312 | 312 | probs.each_with_index do |item, index| |
| 313 | - probs_hash[the_choices[index].id] = item | |
| 313 | + probs_hash[the_choices[index].id] = item | |
| 314 | 314 | end |
| 315 | 315 | probs_hash |
| 316 | 316 | end |
| 317 | 317 | |
| 318 | 318 | |
| 319 | 319 | def all_bt_scores |
| 320 | - btprobs = bradley_terry_probs | |
| 321 | - btprobs.each do |key, value| | |
| 322 | - c = Choice.find(key) | |
| 323 | - puts "#{c.id}: #{c.votes.size} #{c.compute_bt_score(btprobs)}" | |
| 324 | - end | |
| 320 | + btprobs = bradley_terry_probs | |
| 321 | + btprobs.each do |key, value| | |
| 322 | + c = Choice.find(key) | |
| 323 | + puts "#{c.id}: #{c.votes.size} #{c.compute_bt_score(btprobs)}" | |
| 324 | + end | |
| 325 | 325 | |
| 326 | 326 | end |
| 327 | 327 | |
| ... | ... | @@ -388,36 +388,36 @@ class Question < ActiveRecord::Base |
| 388 | 388 | |
| 389 | 389 | is_user_created = {} |
| 390 | 390 | self.choices.each do |c| |
| 391 | - is_user_created[c.id] = c.user_created | |
| 391 | + is_user_created[c.id] = c.user_created | |
| 392 | 392 | end |
| 393 | 393 | |
| 394 | 394 | |
| 395 | 395 | #the_prompts = prompts.find(:all, :include => ['left_choice', 'right_choice']) |
| 396 | 396 | prompts.find_each do |p| |
| 397 | 397 | |
| 398 | - num_appearances = num_appearances_by_prompt[p.id] | |
| 399 | - | |
| 400 | - if num_appearances.nil? | |
| 401 | - num_appearances = 0 | |
| 402 | - end | |
| 403 | - | |
| 404 | - left_user_created = is_user_created[p.left_choice_id] | |
| 405 | - right_user_created = is_user_created[p.right_choice_id] | |
| 406 | - | |
| 407 | - | |
| 408 | - if left_user_created == false && right_user_created == false | |
| 409 | - seed_seed_sum += num_appearances | |
| 410 | - seed_seed_total +=1 | |
| 411 | - elsif left_user_created == false && right_user_created == true | |
| 412 | - seed_nonseed_sum += num_appearances | |
| 413 | - seed_nonseed_total +=1 | |
| 414 | - elsif left_user_created == true && right_user_created == false | |
| 415 | - nonseed_seed_sum += num_appearances | |
| 416 | - nonseed_seed_total +=1 | |
| 417 | - elsif left_user_created == true && right_user_created == true | |
| 418 | - nonseed_nonseed_sum += num_appearances | |
| 419 | - nonseed_nonseed_total +=1 | |
| 420 | - end | |
| 398 | + num_appearances = num_appearances_by_prompt[p.id] | |
| 399 | + | |
| 400 | + if num_appearances.nil? | |
| 401 | + num_appearances = 0 | |
| 402 | + end | |
| 403 | + | |
| 404 | + left_user_created = is_user_created[p.left_choice_id] | |
| 405 | + right_user_created = is_user_created[p.right_choice_id] | |
| 406 | + | |
| 407 | + | |
| 408 | + if left_user_created == false && right_user_created == false | |
| 409 | + seed_seed_sum += num_appearances | |
| 410 | + seed_seed_total +=1 | |
| 411 | + elsif left_user_created == false && right_user_created == true | |
| 412 | + seed_nonseed_sum += num_appearances | |
| 413 | + seed_nonseed_total +=1 | |
| 414 | + elsif left_user_created == true && right_user_created == false | |
| 415 | + nonseed_seed_sum += num_appearances | |
| 416 | + nonseed_seed_total +=1 | |
| 417 | + elsif left_user_created == true && right_user_created == true | |
| 418 | + nonseed_nonseed_sum += num_appearances | |
| 419 | + nonseed_nonseed_total +=1 | |
| 420 | + end | |
| 421 | 421 | end |
| 422 | 422 | |
| 423 | 423 | densities = {} |
| ... | ... | @@ -437,175 +437,175 @@ class Question < ActiveRecord::Base |
| 437 | 437 | |
| 438 | 438 | def save_densities! |
| 439 | 439 | |
| 440 | - d_hash = density | |
| 440 | + d_hash = density | |
| 441 | 441 | |
| 442 | - d_hash.each do |type, average| | |
| 443 | - d = Density.new | |
| 444 | - d.question_id = self.id | |
| 445 | - d.prompt_type = type.to_s | |
| 446 | - d.value = average.nan? ? nil : average | |
| 447 | - d.save! | |
| 448 | - end | |
| 442 | + d_hash.each do |type, average| | |
| 443 | + d = Density.new | |
| 444 | + d.question_id = self.id | |
| 445 | + d.prompt_type = type.to_s | |
| 446 | + d.value = average.nan? ? nil : average | |
| 447 | + d.save! | |
| 448 | + end | |
| 449 | 449 | end |
| 450 | 450 | |
| 451 | 451 | def pq_key |
| 452 | - @pq_key ||= "#{self.id}_prompt_queue" | |
| 452 | + @pq_key ||= "#{self.id}_prompt_queue" | |
| 453 | 453 | end |
| 454 | 454 | |
| 455 | 455 | def clear_prompt_queue |
| 456 | - $redis.del(self.pq_key) | |
| 456 | + $redis.del(self.pq_key) | |
| 457 | 457 | end |
| 458 | 458 | |
| 459 | 459 | def add_prompt_to_queue |
| 460 | - prompt = self.catchup_choose_prompt | |
| 461 | - $redis.rpush(self.pq_key, prompt.id) | |
| 462 | - prompt | |
| 460 | + prompt = self.catchup_choose_prompt | |
| 461 | + $redis.rpush(self.pq_key, prompt.id) | |
| 462 | + prompt | |
| 463 | 463 | end |
| 464 | 464 | |
| 465 | 465 | def pop_prompt_queue |
| 466 | - begin | |
| 467 | - prompt_id = $redis.lpop(self.pq_key) | |
| 468 | - prompt = prompt_id.nil? ? nil : Prompt.find(prompt_id.to_i) | |
| 466 | + begin | |
| 467 | + prompt_id = $redis.lpop(self.pq_key) | |
| 468 | + prompt = prompt_id.nil? ? nil : Prompt.find(prompt_id.to_i) | |
| 469 | 469 | end until (prompt.nil? || prompt.active?) |
| 470 | 470 | prompt |
| 471 | 471 | end |
| 472 | 472 | |
| 473 | 473 | def record_prompt_cache_miss |
| 474 | - $redis.incr(self.pq_key + "_" + Time.now.to_date.to_s + "_"+ "misses") | |
| 474 | + $redis.incr(self.pq_key + "_" + Time.now.to_date.to_s + "_"+ "misses") | |
| 475 | 475 | end |
| 476 | 476 | |
| 477 | 477 | def record_prompt_cache_hit |
| 478 | - $redis.incr(self.pq_key + "_" + Time.now.to_date.to_s + "_"+ "hits") | |
| 478 | + $redis.incr(self.pq_key + "_" + Time.now.to_date.to_s + "_"+ "hits") | |
| 479 | 479 | end |
| 480 | 480 | |
| 481 | 481 | def get_prompt_cache_misses(date) |
| 482 | - $redis.get(self.pq_key + "_" + date.to_s + "_"+ "misses") | |
| 482 | + $redis.get(self.pq_key + "_" + date.to_s + "_"+ "misses") | |
| 483 | 483 | end |
| 484 | 484 | def get_prompt_cache_hits(date) |
| 485 | - $redis.get(self.pq_key + "_" + date.to_s + "_"+ "hits") | |
| 485 | + $redis.get(self.pq_key + "_" + date.to_s + "_"+ "hits") | |
| 486 | 486 | end |
| 487 | 487 | |
| 488 | 488 | def reset_cache_tracking_keys(date) |
| 489 | - $redis.del(self.pq_key + "_" + date.to_s + "_"+ "misses") | |
| 490 | - $redis.del(self.pq_key + "_" + date.to_s + "_"+ "hits") | |
| 489 | + $redis.del(self.pq_key + "_" + date.to_s + "_"+ "misses") | |
| 490 | + $redis.del(self.pq_key + "_" + date.to_s + "_"+ "hits") | |
| 491 | 491 | end |
| 492 | 492 | |
| 493 | 493 | |
| 494 | 494 | def expire_prompt_cache_tracking_keys(date, expire_time = 24*60*60 * 3) # default expires in three days |
| 495 | - $redis.expire(self.pq_key + "_" + date.to_s + "_"+ "hits", expire_time) | |
| 496 | - $redis.expire(self.pq_key + "_" + date.to_s + "_"+ "misses", expire_time) | |
| 495 | + $redis.expire(self.pq_key + "_" + date.to_s + "_"+ "hits", expire_time) | |
| 496 | + $redis.expire(self.pq_key + "_" + date.to_s + "_"+ "misses", expire_time) | |
| 497 | 497 | end |
| 498 | 498 | |
| 499 | 499 | |
| 500 | 500 | def export_and_delete(type, options={}) |
| 501 | - delete_at = options.delete(:delete_at) | |
| 502 | - filename = export(type, options) | |
| 501 | + delete_at = options.delete(:delete_at) | |
| 502 | + filename = export(type, options) | |
| 503 | 503 | |
| 504 | - File.send_at(delete_at, :delete, filename) | |
| 505 | - filename | |
| 504 | + File.send_at(delete_at, :delete, filename) | |
| 505 | + filename | |
| 506 | 506 | end |
| 507 | 507 | |
| 508 | 508 | def export(type, options = {}) |
| 509 | 509 | |
| 510 | 510 | case type |
| 511 | 511 | when 'votes' |
| 512 | - outfile = "ideamarketplace_#{self.id}_votes.csv" | |
| 512 | + outfile = "ideamarketplace_#{self.id}_votes.csv" | |
| 513 | 513 | |
| 514 | - headers = ['Vote ID', 'Session ID', 'Question ID','Winner ID', 'Winner Text', 'Loser ID', 'Loser Text', | |
| 515 | - 'Prompt ID', 'Left Choice ID', 'Right Choice ID', 'Created at', 'Updated at', 'Appearance ID', | |
| 516 | - 'Response Time (s)', 'Missing Response Time Explanation', 'Session Identifier'] | |
| 514 | + headers = ['Vote ID', 'Session ID', 'Question ID','Winner ID', 'Winner Text', 'Loser ID', 'Loser Text', | |
| 515 | + 'Prompt ID', 'Left Choice ID', 'Right Choice ID', 'Created at', 'Updated at', 'Appearance ID', | |
| 516 | + 'Response Time (s)', 'Missing Response Time Explanation', 'Session Identifier'] | |
| 517 | 517 | |
| 518 | 518 | when 'ideas' |
| 519 | - outfile = "ideamarketplace_#{self.id}_ideas.csv" | |
| 519 | + outfile = "ideamarketplace_#{self.id}_ideas.csv" | |
| 520 | 520 | headers = ['Ideamarketplace ID','Idea ID', 'Idea Text', 'Wins', 'Losses', 'Times involved in Cant Decide', 'Score', |
| 521 | - 'User Submitted', 'Session ID', 'Created at', 'Last Activity', 'Active', | |
| 522 | - 'Appearances on Left', 'Appearances on Right'] | |
| 521 | + 'User Submitted', 'Session ID', 'Created at', 'Last Activity', 'Active', | |
| 522 | + 'Appearances on Left', 'Appearances on Right'] | |
| 523 | 523 | when 'non_votes' |
| 524 | 524 | outfile = "ideamarketplace_#{self.id}_non_votes.csv" |
| 525 | 525 | headers = ['Record Type', 'Record ID', 'Session ID', 'Question ID','Left Choice ID', 'Left Choice Text', |
| 526 | - 'Right Choice ID', 'Right Choice Text', 'Prompt ID', 'Appearance ID', 'Reason', | |
| 527 | - 'Created at', 'Updated at', 'Response Time (s)', 'Missing Response Time Explanation', 'Session Identifier'] | |
| 526 | + 'Right Choice ID', 'Right Choice Text', 'Prompt ID', 'Appearance ID', 'Reason', | |
| 527 | + 'Created at', 'Updated at', 'Response Time (s)', 'Missing Response Time Explanation', 'Session Identifier'] | |
| 528 | 528 | else |
| 529 | - raise "Unsupported export type: #{type}" | |
| 529 | + raise "Unsupported export type: #{type}" | |
| 530 | 530 | end |
| 531 | 531 | |
| 532 | 532 | filename = File.join(File.expand_path(Rails.root), "public", "system", "exports", |
| 533 | - self.id.to_s, Digest::SHA1.hexdigest(outfile + rand(10000000).to_s) + "_" + outfile) | |
| 533 | + self.id.to_s, Digest::SHA1.hexdigest(outfile + rand(10000000).to_s) + "_" + outfile) | |
| 534 | 534 | |
| 535 | 535 | FileUtils::mkdir_p(File.dirname(filename)) |
| 536 | 536 | csv_data = FasterCSV.open(filename, "w") do |csv| |
| 537 | - csv << headers | |
| 537 | + csv << headers | |
| 538 | 538 | |
| 539 | 539 | case type |
| 540 | 540 | when 'votes' |
| 541 | 541 | |
| 542 | 542 | self.votes.find_each(:include => [:prompt, :choice, :loser_choice, :voter]) do |v| |
| 543 | - prompt = v.prompt | |
| 544 | - # these may not exist | |
| 545 | - loser_data = v.loser_choice.nil? ? "" : "'#{v.loser_choice.data.strip}'" | |
| 546 | - left_id = v.prompt.nil? ? "" : v.prompt.left_choice_id | |
| 547 | - right_id = v.prompt.nil? ? "" : v.prompt.right_choice_id | |
| 543 | + prompt = v.prompt | |
| 544 | + # these may not exist | |
| 545 | + loser_data = v.loser_choice.nil? ? "" : "'#{v.loser_choice.data.strip}'" | |
| 546 | + left_id = v.prompt.nil? ? "" : v.prompt.left_choice_id | |
| 547 | + right_id = v.prompt.nil? ? "" : v.prompt.right_choice_id | |
| 548 | 548 | |
| 549 | - time_viewed = v.time_viewed.nil? ? "NA": v.time_viewed.to_f / 1000.0 | |
| 549 | + time_viewed = v.time_viewed.nil? ? "NA": v.time_viewed.to_f / 1000.0 | |
| 550 | 550 | |
| 551 | - csv << [ v.id, v.voter_id, v.question_id, v.choice_id, "'#{v.choice.data.strip}'", v.loser_choice_id, loser_data, | |
| 552 | - v.prompt_id, left_id, right_id, v.created_at, v.updated_at, v.appearance_id, | |
| 553 | - time_viewed, v.missing_response_time_exp , v.voter.identifier] | |
| 554 | - end | |
| 551 | + csv << [ v.id, v.voter_id, v.question_id, v.choice_id, "'#{v.choice.data.strip}'", v.loser_choice_id, loser_data, | |
| 552 | + v.prompt_id, left_id, right_id, v.created_at, v.updated_at, v.appearance_id, | |
| 553 | + time_viewed, v.missing_response_time_exp , v.voter.identifier] | |
| 554 | + end | |
| 555 | 555 | |
| 556 | 556 | when 'ideas' |
| 557 | 557 | self.choices.each do |c| |
| 558 | 558 | user_submitted = c.user_created ? "TRUE" : "FALSE" |
| 559 | - left_prompts_ids = c.prompts_on_the_left.ids_only | |
| 560 | - right_prompts_ids = c.prompts_on_the_right.ids_only | |
| 559 | + left_prompts_ids = c.prompts_on_the_left.ids_only | |
| 560 | + right_prompts_ids = c.prompts_on_the_right.ids_only | |
| 561 | 561 | |
| 562 | - left_appearances = self.appearances.count(:conditions => {:prompt_id => left_prompts_ids}) | |
| 563 | - right_appearances = self.appearances.count(:conditions => {:prompt_id => right_prompts_ids}) | |
| 562 | + left_appearances = self.appearances.count(:conditions => {:prompt_id => left_prompts_ids}) | |
| 563 | + right_appearances = self.appearances.count(:conditions => {:prompt_id => right_prompts_ids}) | |
| 564 | 564 | |
| 565 | - num_skips = self.skips.count(:conditions => {:prompt_id => left_prompts_ids + right_prompts_ids}) | |
| 565 | + num_skips = self.skips.count(:conditions => {:prompt_id => left_prompts_ids + right_prompts_ids}) | |
| 566 | 566 | |
| 567 | - csv << [c.question_id, c.id, "'#{c.data.strip}'", c.wins, c.losses, num_skips, c.score, | |
| 568 | - user_submitted , c.creator_id, c.created_at, c.updated_at, c.active, | |
| 569 | - left_appearances, right_appearances] | |
| 567 | + csv << [c.question_id, c.id, "'#{c.data.strip}'", c.wins, c.losses, num_skips, c.score, | |
| 568 | + user_submitted , c.creator_id, c.created_at, c.updated_at, c.active, | |
| 569 | + left_appearances, right_appearances] | |
| 570 | 570 | end |
| 571 | 571 | when 'non_votes' |
| 572 | - | |
| 573 | - self.appearances.find_each(:include => [:skip, :vote, :voter]) do |a| | |
| 574 | - # we only display skips and orphaned appearances in this csv file | |
| 575 | - unless a.vote.nil? | |
| 576 | - next | |
| 577 | - end | |
| 578 | - | |
| 579 | - #If no skip and no vote, this is an orphaned appearance | |
| 580 | - if a.skip.nil? | |
| 581 | - prompt = a.prompt | |
| 582 | - csv << [ "Orphaned Appearance", a.id, a.voter_id, a.question_id, a.prompt.left_choice.id, a.prompt.left_choice.data.strip, | |
| 583 | - a.prompt.right_choice.id, a.prompt.right_choice.data.strip, a.prompt_id, 'N/A', 'N/A', | |
| 584 | - a.created_at, a.updated_at, 'N/A', '', a.voter.identifier] | |
| 585 | - | |
| 586 | - else | |
| 587 | - | |
| 588 | - #If this appearance belongs to a skip, show information on the skip instead | |
| 589 | - s = a.skip | |
| 590 | - time_viewed = s.time_viewed.nil? ? "NA": s.time_viewed.to_f / 1000.0 | |
| 591 | - prompt = s.prompt | |
| 592 | - csv << [ "Skip", s.id, s.skipper_id, s.question_id, s.prompt.left_choice.id, s.prompt.left_choice.data.strip, | |
| 593 | - s.prompt.right_choice.id, s.prompt.right_choice.data.strip, s.prompt_id, s.appearance_id, s.skip_reason, | |
| 594 | - s.created_at, s.updated_at, time_viewed , s.missing_response_time_exp, s.skipper.identifier] | |
| 595 | - end | |
| 596 | - end | |
| 572 | + | |
| 573 | + self.appearances.find_each(:include => [:skip, :vote, :voter]) do |a| | |
| 574 | + # we only display skips and orphaned appearances in this csv file | |
| 575 | + unless a.vote.nil? | |
| 576 | + next | |
| 577 | + end | |
| 578 | + | |
| 579 | + #If no skip and no vote, this is an orphaned appearance | |
| 580 | + if a.skip.nil? | |
| 581 | + prompt = a.prompt | |
| 582 | + csv << [ "Orphaned Appearance", a.id, a.voter_id, a.question_id, a.prompt.left_choice.id, a.prompt.left_choice.data.strip, | |
| 583 | + a.prompt.right_choice.id, a.prompt.right_choice.data.strip, a.prompt_id, 'N/A', 'N/A', | |
| 584 | + a.created_at, a.updated_at, 'N/A', '', a.voter.identifier] | |
| 585 | + | |
| 586 | + else | |
| 587 | + | |
| 588 | + #If this appearance belongs to a skip, show information on the skip instead | |
| 589 | + s = a.skip | |
| 590 | + time_viewed = s.time_viewed.nil? ? "NA": s.time_viewed.to_f / 1000.0 | |
| 591 | + prompt = s.prompt | |
| 592 | + csv << [ "Skip", s.id, s.skipper_id, s.question_id, s.prompt.left_choice.id, s.prompt.left_choice.data.strip, | |
| 593 | + s.prompt.right_choice.id, s.prompt.right_choice.data.strip, s.prompt_id, s.appearance_id, s.skip_reason, | |
| 594 | + s.created_at, s.updated_at, time_viewed , s.missing_response_time_exp, s.skipper.identifier] | |
| 595 | + end | |
| 596 | + end | |
| 597 | 597 | end |
| 598 | 598 | |
| 599 | 599 | end |
| 600 | 600 | |
| 601 | 601 | if options[:response_type] == 'redis' |
| 602 | 602 | |
| 603 | - if options[:redis_key].nil? | |
| 604 | - raise "No :redis_key specified" | |
| 605 | - end | |
| 606 | - #The client should use blpop to listen for a key | |
| 607 | - #The client is responsible for deleting the redis key (auto expiration results failure in testing) | |
| 608 | - $redis.lpush(options[:redis_key], filename) | |
| 603 | + if options[:redis_key].nil? | |
| 604 | + raise "No :redis_key specified" | |
| 605 | + end | |
| 606 | + #The client should use blpop to listen for a key | |
| 607 | + #The client is responsible for deleting the redis key (auto expiration results failure in testing) | |
| 608 | + $redis.lpush(options[:redis_key], filename) | |
| 609 | 609 | #TODO implement response_type == 'email' for use by customers of the API (not local) |
| 610 | 610 | end |
| 611 | 611 | |
| ... | ... | @@ -614,17 +614,17 @@ class Question < ActiveRecord::Base |
| 614 | 614 | |
| 615 | 615 | def get_first_unanswered_appearance(visitor, offset=0) |
| 616 | 616 | last_appearance = visitor.appearances.find(:first, |
| 617 | - :conditions => {:question_id => self.id, | |
| 618 | - :answerable_id => nil | |
| 619 | - }, | |
| 620 | - :order => 'id ASC', | |
| 621 | - :offset => offset) | |
| 617 | + :conditions => {:question_id => self.id, | |
| 618 | + :answerable_id => nil | |
| 619 | + }, | |
| 620 | + :order => 'id ASC', | |
| 621 | + :offset => offset) | |
| 622 | 622 | if last_appearance && !last_appearance.prompt.active? |
| 623 | - last_appearance.valid_record = false | |
| 624 | - last_appearance.validity_information = "Deactivated Prompt" | |
| 625 | - last_appearance.save | |
| 623 | + last_appearance.valid_record = false | |
| 624 | + last_appearance.validity_information = "Deactivated Prompt" | |
| 625 | + last_appearance.save | |
| 626 | 626 | |
| 627 | - return get_first_unanswered_appearance(visitor) | |
| 627 | + return get_first_unanswered_appearance(visitor) | |
| 628 | 628 | end |
| 629 | 629 | last_appearance |
| 630 | 630 | end | ... | ... |