@ -187,28 +187,8 @@ class ExercisesController < ApplicationController
|
|||||||
count_interventions_today = UserExerciseIntervention.where(user: current_user).where("created_at >= ?", Time.zone.now.beginning_of_day).count
|
count_interventions_today = UserExerciseIntervention.where(user: current_user).where("created_at >= ?", Time.zone.now.beginning_of_day).count
|
||||||
user_got_intervention_in_exercise = UserExerciseIntervention.where(user: current_user, exercise: @exercise).size >= max_intervention_count_per_exercise
|
user_got_intervention_in_exercise = UserExerciseIntervention.where(user: current_user, exercise: @exercise).size >= max_intervention_count_per_exercise
|
||||||
user_got_enough_interventions = count_interventions_today >= max_intervention_count_per_day or user_got_intervention_in_exercise
|
user_got_enough_interventions = count_interventions_today >= max_intervention_count_per_day or user_got_intervention_in_exercise
|
||||||
@is_experimental_course = @course_token and experimental_course?(@course_token)
|
|
||||||
|
|
||||||
@experiment_group = UserGroupSeparator.getInterventionGroup(current_user)
|
|
||||||
|
|
||||||
showInterventions = (@is_experimental_course and not user_solved_exercise and not user_got_enough_interventions) ? "true" : "false"
|
|
||||||
|
|
||||||
case @experiment_group
|
|
||||||
when :rfc_intervention_stale_rfc
|
|
||||||
@show_rfc_interventions = showInterventions
|
|
||||||
when :break_intervention_stale_rfc
|
|
||||||
@show_break_interventions = showInterventions
|
|
||||||
when :no_intervention_stale_rfc
|
|
||||||
when :no_intervention_hide_rfc
|
|
||||||
@hide_rfc_button = "true"
|
|
||||||
when :break_intervention_show_rfc
|
|
||||||
@show_break_interventions = showInterventions
|
|
||||||
when :no_intervention_show_rfc
|
|
||||||
when :rfc_intervention_show_rfc
|
|
||||||
@show_rfc_interventions = showInterventions
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
@show_rfc_interventions = (not user_solved_exercise and not user_got_enough_interventions).to_s
|
||||||
|
|
||||||
|
|
||||||
@search = Search.new
|
@search = Search.new
|
||||||
@ -430,11 +410,6 @@ class ExercisesController < ApplicationController
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if @is_experimental_course and (@rfc_group == :hide_rfc)
|
|
||||||
redirect_to_lti_return_path
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
rfc = @submission.own_unsolved_rfc
|
rfc = @submission.own_unsolved_rfc
|
||||||
if rfc
|
if rfc
|
||||||
# set a message that informs the user that his own RFC should be closed.
|
# set a message that informs the user that his own RFC should be closed.
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
module RequestForCommentsHelper
|
|
||||||
end
|
|
@ -36,31 +36,15 @@ class ProxyExercise < ApplicationRecord
|
|||||||
Rails.logger.debug("retrieved assigned exercise for user #{user.id}: Exercise #{assigned_user_proxy_exercise.exercise}" )
|
Rails.logger.debug("retrieved assigned exercise for user #{user.id}: Exercise #{assigned_user_proxy_exercise.exercise}" )
|
||||||
assigned_user_proxy_exercise.exercise
|
assigned_user_proxy_exercise.exercise
|
||||||
else
|
else
|
||||||
|
Rails.logger.debug("find new matching exercise for user #{user.id}" )
|
||||||
matching_exercise =
|
matching_exercise =
|
||||||
if (token.eql? "e85689d5")
|
begin
|
||||||
Rails.logger.debug("Proxy exercise with token e85689d5, split user in groups..")
|
find_matching_exercise(user)
|
||||||
group = UserGroupSeparator.getGroupExerciseDescriptionTesting(user)
|
rescue => e #fallback
|
||||||
Rails.logger.debug("user assigned to group #{group}")
|
Rails.logger.error("finding matching exercise failed. Fall back to random exercise! Error: #{$!}" )
|
||||||
case group
|
@reason[:reason] = "fallback because of error"
|
||||||
when :group_a
|
@reason[:error] = "#{$!}:\n\t#{e.backtrace.join("\n\t")}"
|
||||||
exercises.where(id: 557).first
|
exercises.where("expected_difficulty > 1").shuffle.first # difficulty should be > 1 to prevent dummy exercise from being chosen.
|
||||||
when :group_b
|
|
||||||
exercises.where(id: 558).first
|
|
||||||
when :group_c
|
|
||||||
exercises.where(id: 559).first
|
|
||||||
when :group_d
|
|
||||||
exercises.where(id: 560).first
|
|
||||||
end
|
|
||||||
else
|
|
||||||
Rails.logger.debug("find new matching exercise for user #{user.id}" )
|
|
||||||
begin
|
|
||||||
find_matching_exercise(user)
|
|
||||||
rescue => e #fallback
|
|
||||||
Rails.logger.error("finding matching exercise failed. Fall back to random exercise! Error: #{$!}" )
|
|
||||||
@reason[:reason] = "fallback because of error"
|
|
||||||
@reason[:error] = "#{$!}:\n\t#{e.backtrace.join("\n\t")}"
|
|
||||||
exercises.where("expected_difficulty > 1").shuffle.first # difficulty should be > 1 to prevent dummy exercise from being chosen.
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
user.user_proxy_exercise_exercises << UserProxyExerciseExercise.create(user: user, exercise: matching_exercise, proxy_exercise: self, reason: @reason.to_json)
|
user.user_proxy_exercise_exercises << UserProxyExerciseExercise.create(user: user, exercise: matching_exercise, proxy_exercise: self, reason: @reason.to_json)
|
||||||
matching_exercise
|
matching_exercise
|
||||||
@ -69,42 +53,27 @@ class ProxyExercise < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def find_matching_exercise(user)
|
def find_matching_exercise(user)
|
||||||
user_group = UserGroupSeparator.getProxyExerciseGroup(user)
|
exercises_user_has_accessed = user.submissions.where("cause IN ('submit','assess')").map{|s| s.exercise}.uniq.compact
|
||||||
case user_group
|
tags_user_has_seen = exercises_user_has_accessed.map{|ex| ex.tags}.uniq.flatten
|
||||||
when :dummy_assigment
|
Rails.logger.debug("exercises_user_has_accessed #{exercises_user_has_accessed.map{|e|e.id}.join(",")}")
|
||||||
rec_ex = select_easiest_exercise(exercises)
|
|
||||||
@reason[:reason] = "dummy group"
|
|
||||||
Rails.logger.debug("assigned user to dummy group, and gave him exercise: #{rec_ex.title}")
|
|
||||||
rec_ex
|
|
||||||
when :random_assigment
|
|
||||||
@reason[:reason] = "random group"
|
|
||||||
ex = exercises.where("expected_difficulty > 1").shuffle.first
|
|
||||||
Rails.logger.debug("assigned user to random group, and gave him exercise: #{ex.title}")
|
|
||||||
ex
|
|
||||||
when :recommended_assignment
|
|
||||||
exercises_user_has_accessed = user.submissions.where("cause IN ('submit','assess')").map{|s| s.exercise}.uniq.compact
|
|
||||||
tags_user_has_seen = exercises_user_has_accessed.map{|ex| ex.tags}.uniq.flatten
|
|
||||||
Rails.logger.debug("exercises_user_has_accessed #{exercises_user_has_accessed.map{|e|e.id}.join(",")}")
|
|
||||||
|
|
||||||
# find exercises
|
# find exercises
|
||||||
potential_recommended_exercises = []
|
potential_recommended_exercises = []
|
||||||
exercises.where("expected_difficulty >= 1").each do |ex|
|
exercises.where("expected_difficulty >= 1").each do |ex|
|
||||||
## find exercises which have only tags the user has already seen
|
## find exercises which have only tags the user has already seen
|
||||||
if (ex.tags - tags_user_has_seen).empty?
|
if (ex.tags - tags_user_has_seen).empty?
|
||||||
potential_recommended_exercises << ex
|
potential_recommended_exercises << ex
|
||||||
end
|
|
||||||
end
|
end
|
||||||
Rails.logger.debug("potential_recommended_exercises: #{potential_recommended_exercises.map{|e|e.id}}")
|
end
|
||||||
# if all exercises contain tags which the user has never seen, recommend easiest exercise
|
Rails.logger.debug("potential_recommended_exercises: #{potential_recommended_exercises.map{|e|e.id}}")
|
||||||
if potential_recommended_exercises.empty?
|
# if all exercises contain tags which the user has never seen, recommend easiest exercise
|
||||||
Rails.logger.debug("matched easiest exercise in pool")
|
if potential_recommended_exercises.empty?
|
||||||
@reason[:reason] = "easiest exercise in pool. empty potential exercises"
|
Rails.logger.debug("matched easiest exercise in pool")
|
||||||
select_easiest_exercise(exercises)
|
@reason[:reason] = "easiest exercise in pool. empty potential exercises"
|
||||||
else
|
select_easiest_exercise(exercises)
|
||||||
select_best_matching_exercise(user, exercises_user_has_accessed, potential_recommended_exercises)
|
else
|
||||||
end
|
select_best_matching_exercise(user, exercises_user_has_accessed, potential_recommended_exercises)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
private :find_matching_exercise
|
private :find_matching_exercise
|
||||||
|
|
||||||
|
@ -66,10 +66,6 @@ class Submission < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def unsolved_rfc
|
def unsolved_rfc
|
||||||
# old query
|
RequestForComment.unsolved.where(exercise_id: exercise).where.not(question: nil).order("RANDOM()").find { | rfc_element |( (rfc_element.comments_count < MAX_COMMENTS_ON_RECOMMENDED_RFC) && (!rfc_element.question.empty?)) }
|
||||||
# RequestForComment.unsolved.where(exercise_id: exercise).where.not(question: nil).order("RANDOM()").find { | rfc_element |(rfc_element.comments_count < MAX_COMMENTS_ON_RECOMMENDED_RFC) }
|
|
||||||
|
|
||||||
# experimental query:
|
|
||||||
RequestForComment.unsolved.joins('JOIN exercise_collection_items eci ON eci.exercise_id = request_for_comments.exercise_id').where('eci.exercise_collection_id != 3 OR user_id%10 > 3').where(exercise_id: exercise).where.not(question: nil).order("RANDOM()").find { | rfc_element |(rfc_element.comments_count < MAX_COMMENTS_ON_RECOMMENDED_RFC) }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -23,8 +23,7 @@ h1 = RequestForComment.model_name.human(count: 2)
|
|||||||
th = t('activerecord.attributes.request_for_comments.last_update')
|
th = t('activerecord.attributes.request_for_comments.last_update')
|
||||||
tbody
|
tbody
|
||||||
- @request_for_comments.each do |request_for_comment|
|
- @request_for_comments.each do |request_for_comment|
|
||||||
- do_not_answer = [:rfc_intervention_stale_rfc, :break_intervention_stale_rfc, :no_intervention_stale_rfc].include?(UserGroupSeparator.getInterventionGroup(request_for_comment.user)) and current_user.internal_user?
|
tr data-id=request_for_comment.id
|
||||||
tr data-id=request_for_comment.id class=('do-not-answer' if do_not_answer)
|
|
||||||
- if request_for_comment.solved?
|
- if request_for_comment.solved?
|
||||||
td
|
td
|
||||||
span class="fa fa-check" aria-hidden="true"
|
span class="fa fa-check" aria-hidden="true"
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
class UserGroupSeparator
|
|
||||||
|
|
||||||
# seperates user into 20% no intervention, 20% break intervention, 60% rfc intervention
|
|
||||||
def self.getInterventionGroup(user)
|
|
||||||
lastDigitId = user.id % 10
|
|
||||||
if lastDigitId < 1 # 0
|
|
||||||
:rfc_intervention_stale_rfc
|
|
||||||
elsif lastDigitId < 2 # 1
|
|
||||||
:break_intervention_stale_rfc
|
|
||||||
elsif lastDigitId < 3 # 2
|
|
||||||
:no_intervention_stale_rfc
|
|
||||||
elsif lastDigitId < 4 # 3
|
|
||||||
:no_intervention_hide_rfc
|
|
||||||
elsif lastDigitId < 5 # 4
|
|
||||||
:break_intervention_show_rfc
|
|
||||||
elsif lastDigitId < 6 # 5
|
|
||||||
:no_intervention_show_rfc
|
|
||||||
else # 6,7,8,9
|
|
||||||
:rfc_intervention_show_rfc
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# seperates user into 20% dummy assignment, 20% random assignemnt, 60% recommended assignment
|
|
||||||
def self.getProxyExerciseGroup(user)
|
|
||||||
lastDigitCreatedAt = user.created_at.to_i % 10
|
|
||||||
if lastDigitCreatedAt < 2 # 0,1
|
|
||||||
:dummy_assigment
|
|
||||||
elsif lastDigitCreatedAt < 4 # 2,3
|
|
||||||
:random_assigment
|
|
||||||
else # 4,5,6,7,8,9
|
|
||||||
:recommended_assignment
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.getGroupExerciseDescriptionTesting(user)
|
|
||||||
groupById = user.id % 4
|
|
||||||
if groupById == 0
|
|
||||||
:group_a
|
|
||||||
elsif groupById == 1
|
|
||||||
:group_b
|
|
||||||
elsif groupById == 2
|
|
||||||
:group_c
|
|
||||||
else # 3
|
|
||||||
:group_d
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
Reference in New Issue
Block a user