diff --git a/app/models/exercise.rb b/app/models/exercise.rb index 0f691fde..0a266532 100644 --- a/app/models/exercise.rb +++ b/app/models/exercise.rb @@ -75,6 +75,30 @@ class Exercise < ActiveRecord::Base """ end + def getQuantiles(quantiles) + quantiles_str = "[" + quantiles.join(",") + "]" + result = self.class.connection.execute(""" + SELECT unnest(PERCENTILE_CONT(ARRAY#{quantiles_str}) WITHIN GROUP (ORDER BY working_time)) + FROM + ( + SELECT user_id, + sum(working_time_new) AS working_time + FROM + (SELECT user_id, + CASE WHEN working_time >= '0:30:00' THEN '0' ELSE working_time END AS working_time_new + FROM + (SELECT user_id, + id, + (created_at - lag(created_at) OVER (PARTITION BY user_id + ORDER BY created_at)) AS working_time + FROM submissions + WHERE exercise_id=69) AS foo) AS bar + GROUP BY user_id + ) AS foo + """) + quantiles.each_with_index.map{|q,i| [q, Time.parse(result[i]["unnest"]).seconds_since_midnight]}.to_h + end + def retrieve_working_time_statistics @working_time_statistics = {} self.class.connection.execute(user_working_time_query).each do |tuple| diff --git a/app/models/proxy_exercise.rb b/app/models/proxy_exercise.rb index 2efa8962..678aeb4a 100644 --- a/app/models/proxy_exercise.rb +++ b/app/models/proxy_exercise.rb @@ -54,11 +54,24 @@ class ProxyExercise < ActiveRecord::Base ] end + def scoring_matrix_quantiles + [0.2,0.4,0.6,0.8] + end + def score(user, ex) points_ratio = ex.maximum_score(user) / ex.maximum_score.to_f + points_ratio_index = points_ratio.to_i working_time_user = Time.parse(ex.average_working_time_for_only(user.id) || "00:00:00") scoring_matrix = scoring_matrix - + quantiles_working_time = ex.getQuantiles(scoring_matrix_quantiles) + quantile_index = quantile_time.size + quantiles_working_time.each_with_index do |quantile_time, i| + if working_time_user <= quantile_time + quantile_index = i + break + end + end + scoring_matrix[points_ratio_index][quantile_index] end def getRelativeKnowledgeLoss(user, execises) @@ -66,11 +79,11 @@ class ProxyExercise < ActiveRecord::Base topic_knowledge_loss_user = Tag.all.map{|t| [t, 0]}.to_h topic_knowledge_max = Tag.all.map{|t| [t, 0]}.to_h execises.each do |ex| - score = score(user, ex) + user_score_factor = score(user, ex) ex.tags.each do |t| tag_ratio = ex.exercise_tags.where(tag: t).factor / ex.exercise_tags.inject(0){|sum, et| sum += et.factor } topic_knowledge = ex.expected_difficulty * tag_ratio - topic_knowledge_loss_user[t] += (1-score) * topic_knowledge + topic_knowledge_loss_user[t] += (1 - user_score_factor) * topic_knowledge topic_knowledge_max[t] += topic_knowledge end end