diff --git a/app/controllers/execution_environments_controller.rb b/app/controllers/execution_environments_controller.rb index eeae03f9..af4323b3 100644 --- a/app/controllers/execution_environments_controller.rb +++ b/app/controllers/execution_environments_controller.rb @@ -55,14 +55,47 @@ class ExecutionEnvironmentsController < ApplicationController """ end + def user_query + """ + SELECT + id AS exercise_id, + COUNT(DISTINCT user_id) AS users, + AVG(score) AS average_score, + MAX(score) AS maximum_score, + CASE + WHEN MAX(score)=0 THEN 0 + ELSE 100 / MAX(score) * AVG(score) + END AS percent_correct, + SUM(submission_count) / COUNT(DISTINCT user_id) AS average_submission_count + FROM + (SELECT e.id, + s.user_id, + MAX(s.score) AS score, + COUNT(s.id) AS submission_count + FROM submissions s + JOIN exercises e ON e.id = s.exercise_id + WHERE e.execution_environment_id = #{@execution_environment.id} + GROUP BY e.id, + s.user_id) AS inner_query + GROUP BY id; + """ + end + def statistics working_time_statistics = {} + user_statistics = {} + ActiveRecord::Base.connection.execute(working_time_query).each do |tuple| working_time_statistics[tuple["exercise_id"].to_i] = tuple end + ActiveRecord::Base.connection.execute(user_query).each do |tuple| + user_statistics[tuple["exercise_id"].to_i] = tuple + end + render locals: { - working_time_statistics: working_time_statistics + working_time_statistics: working_time_statistics, + user_statistics: user_statistics } end diff --git a/app/models/exercise.rb b/app/models/exercise.rb index 6e7acdea..6fe198ac 100644 --- a/app/models/exercise.rb +++ b/app/models/exercise.rb @@ -34,7 +34,7 @@ class Exercise < ActiveRecord::Base def average_score if submissions.exists?(cause: 'submit') - maximum_scores_query = submissions.select('MAX(score) AS maximum_score').where(cause: 'submit').group(:user_id).to_sql.sub('$1', id.to_s) + maximum_scores_query = submissions.select('MAX(score) AS maximum_score').group(:user_id).to_sql.sub('$1', id.to_s) self.class.connection.execute("SELECT AVG(maximum_score) AS average_score FROM (#{maximum_scores_query}) AS maximum_scores").first['average_score'].to_f else 0 end end diff --git a/app/views/execution_environments/statistics.html.slim b/app/views/execution_environments/statistics.html.slim index e0141e7e..97c58ee4 100644 --- a/app/views/execution_environments/statistics.html.slim +++ b/app/views/execution_environments/statistics.html.slim @@ -8,14 +8,15 @@ h1 = @execution_environment th.header = t(title) tbody - @execution_environment.exercises.each do |exercise| - - average_score = exercise.average_score + - us = user_statistics[exercise.id] + - if not us then us = {"users" => 0, "average_score" => 0.0, "maximum_score" => 0, "percent_correct" => nil, "average_submission_count" => 0} - wts = working_time_statistics[exercise.id] - if wts then average_time = wts["average_time"] else 0 tr td = link_to exercise.title, controller: "exercises", action: "statistics", id: exercise.id - td = exercise.users.distinct.count - td = average_score - td = exercise.maximum_score - td = 100 / exercise.maximum_score * average_score - td = exercise.average_number_of_submissions + td = us["users"] + td = us["average_score"] + td = us["maximum_score"] + td = us["percent_correct"] + td = us["average_submission_count"] td = average_time