Description:
add more problem stat
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r457:c81651eecbbd - - 7 files changed: 144 inserted, 43 deleted

@@ -0,0 +1,44
1 + - param = {} unless param
2 + - graph_height = param[:graph_height] || 100
3 + - bar_width = param[:bar_width] || 14
4 + - graph_width = (bar_width * histogram[:data].count) + 20
5 + :css
6 + .hist_bar {
7 + width: #{bar_width-1}px;
8 + position: absolute;
9 + background-color: lightblue;
10 + }
11 + .hist_fill {
12 + width: #{bar_width-1}px;
13 + position: absolute;
14 + background-color: #eee;
15 + }
16 + .hist_text {
17 + position: absolute;
18 + font-size:5px;
19 + }
20 +
21 + %div{style: "position: relative; width: #{graph_width}px; height: 150px; background-color:#fff;" }
22 + //draw background
23 + - histogram[:data].each_index do |i|
24 + - height = histogram[:data][i] * graph_height / histogram[:summary][:max]
25 + - top = graph_height - height
26 + - left = graph_width - (i+1)*bar_width
27 + %div.hist_fill{style: "top: 0px; height: #{graph_height - height}px; left: #{left}px;" }
28 + // draw horizontal line
29 + - line = 3
30 + - line.times do |i|
31 + - top = graph_height - graph_height * (i+0.5)/ line
32 + %div{style: "position:absolute;width: #{graph_width-21}px;height: 1px;left: 20px;top:#{top}px;background-color: #333;"}
33 + %div.hist_text{style: "position:absolute;left: 0px;top:#{top-6}px"}
34 + =((i+0.5) * histogram[:summary][:max] / line).to_i
35 + // draw the actual bar and text
36 + - @histogram[:data].each_index do |i|
37 + - height = histogram[:data][i] * graph_height / histogram[:summary][:max]
38 + - top = graph_height - height
39 + - left = graph_width - (i+1)*bar_width
40 + %div.hist_bar{style: "top: #{top}px; height: #{height}px; left: #{left}px; dae: #{histogram[:data][i]}" }
41 + - if i % 7 == 1
42 + %div.hist_text{style: "top:#{graph_height + 5}px;left: #{left}px;"} #{(Time.zone.today - i.day).strftime('%-d')}
43 + - if (Time.now.in_time_zone - i.day).day == 15
44 + %div.hist_text{style: "top:#{graph_height + 15}px;left: #{left}px;"} #{(Time.zone.today - i.day).strftime('%b')}
@@ -150,11 +150,26
150
150
151 def stat
151 def stat
152 @problem = Problem.find(params[:id])
152 @problem = Problem.find(params[:id])
153 - if !@problem.available
153 + unless @problem.available or session[:admin]
154 redirect_to :controller => 'main', :action => 'list'
154 redirect_to :controller => 'main', :action => 'list'
155 - else
155 + return
156 + end
156 @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id)
157 @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id)
158 +
159 + #stat summary
160 + range =65
161 + @histogram = { data: Array.new(range,0), summary: {} }
162 + @histogram[:data] = Array.new(range,0)
163 + user = Hash.new(0)
164 + @submissions.find_each do |sub|
165 + d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
166 + @histogram[:data][d.to_i] += 1 if d < range
167 + user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
157 end
168 end
169 + @histogram[:summary][:max] = [@histogram[:data].max,1].max
170 +
171 + @summary = { attempt: user.count, solve: 0 }
172 + user.each_value { |v| @summary[:solve] += 1 if v == 1 }
158 end
173 end
159
174
160 def manage
175 def manage
@@ -257,4 +272,7
257 problems
272 problems
258 end
273 end
259
274
275 + def get_problems_stat
260 end
276 end
277 +
278 + end
@@ -105,10 +105,23
105 end
105 end
106 end
106 end
107
107
108 - if @problem
108 + return unless @problem
109 - #aggregrate by language
109 +
110 - @by_lang = {}
110 + @by_lang = {} #aggregrate by language
111 +
112 + range =65
113 + @histogram = { data: Array.new(range,0), summary: {} }
114 + @histogram[:data] = Array.new(range,0)
115 + @summary = {count: 0, solve: 0, attempt: 0}
116 + user = Hash.new(0)
111 Submission.where(problem_id: @problem.id).find_each do |sub|
117 Submission.where(problem_id: @problem.id).find_each do |sub|
118 + #histogram
119 + d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
120 + @histogram[:data][d.to_i] += 1 if d < range
121 +
122 + @summary[:count] += 1
123 + user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
124 +
112 lang = Language.find_by_id(sub.language_id)
125 lang = Language.find_by_id(sub.language_id)
113 next unless lang
126 next unless lang
114 next unless sub.points >= @problem.full_score
127 next unless sub.points >= @problem.full_score
@@ -124,40 +137,20
124 end
137 end
125
138
126 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
139 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
127 - @by_lang[lang.pretty_name][:runtime] = {
140 + @by_lang[lang.pretty_name][:runtime] = { avail: true, user_id: sub.user_id, value: sub.max_runtime, sub_id: sub.id }
128 - avail: true,
129 - user_id: sub.user_id,
130 - value: sub.max_runtime,
131 - sub_id: sub.id
132 - }
133 end
141 end
134
142
135 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
143 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
136 - @by_lang[lang.pretty_name][:memory] = {
144 + @by_lang[lang.pretty_name][:memory] = { avail: true, user_id: sub.user_id, value: sub.peak_memory, sub_id: sub.id }
137 - avail: true,
138 - user_id: sub.user_id,
139 - value: sub.peak_memory,
140 - sub_id: sub.id
141 - }
142 end
145 end
143
146
144 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and
147 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and
145 !sub.user.admin?
148 !sub.user.admin?
146 - @by_lang[lang.pretty_name][:first] = {
149 + @by_lang[lang.pretty_name][:first] = { avail: true, user_id: sub.user_id, value: sub.submitted_at, sub_id: sub.id }
147 - avail: true,
148 - user_id: sub.user_id,
149 - value: sub.submitted_at,
150 - sub_id: sub.id
151 - }
152 end
150 end
153
151
154 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
152 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
155 - @by_lang[lang.pretty_name][:length] = {
153 + @by_lang[lang.pretty_name][:length] = { avail: true, user_id: sub.user_id, value: sub.effective_code_length, sub_id: sub.id }
156 - avail: true,
157 - user_id: sub.user_id,
158 - value: sub.effective_code_length,
159 - sub_id: sub.id
160 - }
161 end
154 end
162 end
155 end
163
156
@@ -190,6 +183,10
190 end
183 end
191 end
184 end
192 end
185 end
193 - end
186 +
187 + @histogram[:summary][:max] = [@histogram[:data].max,1].max
188 + @summary[:attempt] = user.count
189 + user.each_value { |v| @summary[:solve] += 1 if v == 1 }
194 end
190 end
191 +
195 end
192 end
@@ -55,6 +55,13
55 return "#{Rails.root}/data/tasks"
55 return "#{Rails.root}/data/tasks"
56 end
56 end
57
57
58 + def get_submission_stat
59 + result = Hash.new
60 + #total number of submission
61 + result[:total_sub] = Submission.where(problem_id: self.id).count
62 + result[:attempted_user] = Submission.where(problem_id: self.id).group_by(:user_id)
63 + end
64 +
58 protected
65 protected
59
66
60 def self.to_i_or_default(st, default)
67 def self.to_i_or_default(st, default)
@@ -6,6 +6,23
6 %h1 Problem stat: #{@problem.name}
6 %h1 Problem stat: #{@problem.name}
7 %h2 Overview
7 %h2 Overview
8
8
9 +
10 + %table.info
11 + %thead
12 + %tr.info-head
13 + %th Stat
14 + %th Value
15 + %tbody
16 + %tr{class: cycle('info-even','info-odd')}
17 + %td Submissions
18 + %td= @submissions.count
19 + %tr{class: cycle('info-even','info-odd')}
20 + %td Solved/Attempted User
21 + %td #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
22 +
23 + %h2 Submissions Count
24 + = render partial: 'application/bar_graph', locals: { histogram: @histogram }
25 +
9 %h2 Submissions
26 %h2 Submissions
10 - if @submissions and @submissions.count > 0
27 - if @submissions and @submissions.count > 0
11 %table.info#main_table
28 %table.info#main_table
@@ -2,47 +2,66
2 .hof_user { color: orangered; font-style: italic; }
2 .hof_user { color: orangered; font-style: italic; }
3 .hof_language { color: green; font-style: italic; }
3 .hof_language { color: green; font-style: italic; }
4 .hof_value { color: deeppink;font-style: italic; }
4 .hof_value { color: deeppink;font-style: italic; }
5 + .info_param { font-weight: bold;text-align: right; }
5
6
6 - %h2 Overall of #{Problem.find(params[:id]).full_name}
7 + %h1 (#{Problem.find(params[:id]).name}) #{Problem.find(params[:id]).full_name}
7
8
9 + %h2 Problem Stat
10 + %table.info
11 + %thead
12 + %tr.info-head
13 + %th Stat
14 + %th Value
15 + %tbody
16 + %tr{class: cycle('info-even','info-odd')}
17 + %td.info_param Submissions
18 + %td= @summary[:count]
19 + %tr{class: cycle('info-even','info-odd')}
20 + %td.info_param Solved/Attempted User
21 + %td #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
8 - if @best
22 - if @best
9 - %b Best Runtime:
23 + %tr{class: cycle('info-even','info-odd')}
24 + %td.info_param Best Runtime
25 + %td
10 by #{link_to @best[:runtime][:user], controller:'users', action:'profile', id:@best[:memory][:user_id]}
26 by #{link_to @best[:runtime][:user], controller:'users', action:'profile', id:@best[:memory][:user_id]}
11 using <span class="hof_language">#{@best[:runtime][:lang]}</span>
27 using <span class="hof_language">#{@best[:runtime][:lang]}</span>
12 with <span class="hof_value">#{@best[:runtime][:value] * 1000} milliseconds</span>
28 with <span class="hof_value">#{@best[:runtime][:value] * 1000} milliseconds</span>
13 at submission
29 at submission
14 = link_to("#" + @best[:runtime][:sub_id].to_s, controller: 'graders', action: 'submission', id:@best[:runtime][:sub_id])
30 = link_to("#" + @best[:runtime][:sub_id].to_s, controller: 'graders', action: 'submission', id:@best[:runtime][:sub_id])
15 - %br/
16
31
17 - %b Best Memory Usage:
32 + %tr{class: cycle('info-even','info-odd')}
33 + %td.info_param Best Memory Usage
34 + %td
18 by #{link_to @best[:memory][:user], controller:'users', action:'profile', id:@best[:memory][:user_id]}
35 by #{link_to @best[:memory][:user], controller:'users', action:'profile', id:@best[:memory][:user_id]}
19 using <span class="hof_language">#{@best[:memory][:lang]}</span>
36 using <span class="hof_language">#{@best[:memory][:lang]}</span>
20 with <span class="hof_value">#{number_with_delimiter(@best[:memory][:value])} kbytes </span>
37 with <span class="hof_value">#{number_with_delimiter(@best[:memory][:value])} kbytes </span>
21 at submission
38 at submission
22 = link_to("#" + @best[:memory][:sub_id].to_s, controller: 'graders' , action: 'submission', id:@best[:memory][:sub_id])
39 = link_to("#" + @best[:memory][:sub_id].to_s, controller: 'graders' , action: 'submission', id:@best[:memory][:sub_id])
23 - %br/
24
40
25 - %b Shortest Code:
41 + %tr{class: cycle('info-even','info-odd')}
42 + %td.info_param Shortest Code
43 + %td
26 by #{link_to @best[:length][:user], controller:'users', action:'profile', id:@best[:length][:user_id]}
44 by #{link_to @best[:length][:user], controller:'users', action:'profile', id:@best[:length][:user_id]}
27 using <span class="hof_language">#{@best[:length][:lang]}</span>
45 using <span class="hof_language">#{@best[:length][:lang]}</span>
28 with <span class="hof_value">#{@best[:length][:value]} bytes</span>
46 with <span class="hof_value">#{@best[:length][:value]} bytes</span>
29 at submission
47 at submission
30 = link_to("#" + @best[:length][:sub_id].to_s, controller: 'graders' , action: 'submission', id: @best[:length][:sub_id])
48 = link_to("#" + @best[:length][:sub_id].to_s, controller: 'graders' , action: 'submission', id: @best[:length][:sub_id])
31 - %br/
32
49
33 - %b First solver:
50 + %tr{class: cycle('info-even','info-odd')}
51 + %td.info_param First solver
52 + %td
34 #{link_to @best[:first][:user], controller:'users', action:'profile', id:@best[:first][:user_id]} is the first solver
53 #{link_to @best[:first][:user], controller:'users', action:'profile', id:@best[:first][:user_id]} is the first solver
35 using <span class="hof_language">#{@best[:first][:lang]}</span>
54 using <span class="hof_language">#{@best[:first][:lang]}</span>
36 on <span class="hof_value">#{@best[:first][:value]}</span>
55 on <span class="hof_value">#{@best[:first][:value]}</span>
37 at submission
56 at submission
38 = link_to("#" + @best[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: @best[:first][:sub_id])
57 = link_to("#" + @best[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: @best[:first][:sub_id])
39 - %br/
40
58
41
59
42 %p
60 %p
43 This counts only for submission with 100% score <br/>
61 This counts only for submission with 100% score <br/>
44 Right now, java is excluded from memory usage competition. (Because it always uses 2GB memory...)
62 Right now, java is excluded from memory usage competition. (Because it always uses 2GB memory...)
45
63
64 + - if @best
46 %h2 By language
65 %h2 By language
47
66
48 %table.info
67 %table.info
@@ -75,5 +94,3
75 = "(#{value[:first][:value]} @"
94 = "(#{value[:first][:value]} @"
76 = "#{link_to("#" + value[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:first][:sub_id])} )".html_safe
95 = "#{link_to("#" + value[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:first][:sub_id])} )".html_safe
77
96
78 - - else
79 - %h3 No submissions
@@ -6,7 +6,7
6 / %h1 All-Time Hall of Fame
6 / %h1 All-Time Hall of Fame
7
7
8
8
9 - %h1 Tasks Hall of Fame
9 + %h1 Hall of Fame
10 .task-menu
10 .task-menu
11 Tasks
11 Tasks
12 %br/
12 %br/
@@ -18,5 +18,6
18 Please select a problem.
18 Please select a problem.
19 - else
19 - else
20 =render partial: 'task_hof'
20 =render partial: 'task_hof'
21 + %h2 Submission History
22 + =render partial: 'application/bar_graph', locals: { histogram: @histogram }
21
23
22 -
You need to be logged in to leave comments. Login now