Description:
grades contest submissions
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r385:865ba2aed5c0 - - 3 files changed: 73 inserted, 25 deleted

@@ -0,0 +1,47
1 + #!/usr/bin/env ruby
2 +
3 + APP_PATH = File.expand_path('../../config/application', __FILE__)
4 + require File.expand_path('../../config/boot', __FILE__)
5 + require APP_PATH
6 +
7 + # set Rails.env here if desired
8 + Rails.application.require_environment!
9 +
10 + def main
11 + if ARGV.length != 1
12 + puts "Usage: contest_grade_prob.rb [problem_name]"
13 + exit(0)
14 + end
15 +
16 + problem_name = ARGV[0]
17 + problem = Problem.where(:name => problem_name).first
18 + if !problem
19 + puts "Problem not found"
20 + exit(0)
21 + end
22 +
23 + problem.full_score = 100
24 + problem.save
25 +
26 + test_pair = TestPair.get_for(problem, true)
27 +
28 + User.all.each do |u|
29 + puts "#{u.login}:"
30 + submissions = Submission.find_all_by_user_problem(u.id, problem.id)
31 + submissions.each do |sub|
32 + result = test_pair.grade(sub.output)
33 + result2 = test_pair.grade(sub.source)
34 + if result2[:score] > result[:score]
35 + result = result2
36 + puts "Use source field (#{sub.id})"
37 + end
38 +
39 + full_score = result[:full_score]
40 + sub.points = result[:score]*100 / full_score
41 + sub.grader_comment = result[:msg]
42 + sub.save
43 + end
44 + end
45 + end
46 +
47 + main
@@ -97,420 +97,396
97
97
98 if GraderConfiguration.time_limit_mode? and user.contest_finished?
98 if GraderConfiguration.time_limit_mode? and user.contest_finished?
99 @submission.errors.add(:base,"The contest is over.")
99 @submission.errors.add(:base,"The contest is over.")
100 prepare_list_information
100 prepare_list_information
101 render :action => 'list' and return
101 render :action => 'list' and return
102 end
102 end
103
103
104 if @submission.valid?
104 if @submission.valid?
105 if @submission.save == false
105 if @submission.save == false
106 flash[:notice] = 'Error saving your submission'
106 flash[:notice] = 'Error saving your submission'
107 elsif Task.create(:submission_id => @submission.id,
107 elsif Task.create(:submission_id => @submission.id,
108 :status => Task::STATUS_INQUEUE) == false
108 :status => Task::STATUS_INQUEUE) == false
109 flash[:notice] = 'Error adding your submission to task queue'
109 flash[:notice] = 'Error adding your submission to task queue'
110 else
110 else
111 flash[:notice] = 'จัดเก็บคำตอบและโปรแกรมที่คุณส่งเรียบร้อย'
111 flash[:notice] = 'จัดเก็บคำตอบและโปรแกรมที่คุณส่งเรียบร้อย'
112 end
112 end
113 else
113 else
114 prepare_list_information
114 prepare_list_information
115 render :action => 'list' and return
115 render :action => 'list' and return
116 end
116 end
117
117
118 if @current_problem
118 if @current_problem
119 session[:current_problem_id] = @current_problem.id
119 session[:current_problem_id] = @current_problem.id
120 end
120 end
121 redirect_to :action => 'list'
121 redirect_to :action => 'list'
122 end
122 end
123
123
124 def source
124 def source
125 submission = Submission.find(params[:id])
125 submission = Submission.find(params[:id])
126 if ((submission.user_id == session[:user_id]) and
126 if ((submission.user_id == session[:user_id]) and
127 (submission.problem != nil) and
127 (submission.problem != nil) and
128 (submission.problem.available))
128 (submission.problem.available))
129 send_data(submission.source,
129 send_data(submission.source,
130 {:filename => submission.download_filename,
130 {:filename => submission.download_filename,
131 :type => 'text/plain'})
131 :type => 'text/plain'})
132 else
132 else
133 flash[:notice] = 'Error viewing source'
133 flash[:notice] = 'Error viewing source'
134 redirect_to :action => 'list'
134 redirect_to :action => 'list'
135 end
135 end
136 end
136 end
137
137
138 def compiler_msg
138 def compiler_msg
139 @submission = Submission.find(params[:id])
139 @submission = Submission.find(params[:id])
140 if @submission.user_id == session[:user_id]
140 if @submission.user_id == session[:user_id]
141 render :action => 'compiler_msg', :layout => 'empty'
141 render :action => 'compiler_msg', :layout => 'empty'
142 else
142 else
143 flash[:notice] = 'Error viewing source'
143 flash[:notice] = 'Error viewing source'
144 redirect_to :action => 'list'
144 redirect_to :action => 'list'
145 end
145 end
146 end
146 end
147
147
148 def submission
148 def submission
149 @user = User.find(session[:user_id])
149 @user = User.find(session[:user_id])
150 @problems = @user.available_problems
150 @problems = @user.available_problems
151 if params[:id]==nil
151 if params[:id]==nil
152 @problem = nil
152 @problem = nil
153 @submissions = nil
153 @submissions = nil
154 else
154 else
155 @problem = Problem.find_by_name(params[:id])
155 @problem = Problem.find_by_name(params[:id])
156 if not @problem.available
156 if not @problem.available
157 redirect_to :action => 'list'
157 redirect_to :action => 'list'
158 flash[:notice] = 'Error: submissions for that problem are not viewable.'
158 flash[:notice] = 'Error: submissions for that problem are not viewable.'
159 return
159 return
160 end
160 end
161 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
161 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
162 end
162 end
163 end
163 end
164
164
165 def result
165 def result
166 if !GraderConfiguration.show_grading_result
166 if !GraderConfiguration.show_grading_result
167 redirect_to :action => 'list' and return
167 redirect_to :action => 'list' and return
168 end
168 end
169 @user = User.find(session[:user_id])
169 @user = User.find(session[:user_id])
170 @submission = Submission.find(params[:id])
170 @submission = Submission.find(params[:id])
171 if @submission.user!=@user
171 if @submission.user!=@user
172 flash[:notice] = 'You are not allowed to view result of other users.'
172 flash[:notice] = 'You are not allowed to view result of other users.'
173 redirect_to :action => 'list' and return
173 redirect_to :action => 'list' and return
174 end
174 end
175 prepare_grading_result(@submission)
175 prepare_grading_result(@submission)
176 end
176 end
177
177
178 def load_output
178 def load_output
179 if !GraderConfiguration.show_grading_result or params[:num]==nil
179 if !GraderConfiguration.show_grading_result or params[:num]==nil
180 redirect_to :action => 'list' and return
180 redirect_to :action => 'list' and return
181 end
181 end
182 @user = User.find(session[:user_id])
182 @user = User.find(session[:user_id])
183 @submission = Submission.find(params[:id])
183 @submission = Submission.find(params[:id])
184 if @submission.user!=@user
184 if @submission.user!=@user
185 flash[:notice] = 'You are not allowed to view result of other users.'
185 flash[:notice] = 'You are not allowed to view result of other users.'
186 redirect_to :action => 'list' and return
186 redirect_to :action => 'list' and return
187 end
187 end
188 case_num = params[:num].to_i
188 case_num = params[:num].to_i
189 out_filename = output_filename(@user.login,
189 out_filename = output_filename(@user.login,
190 @submission.problem.name,
190 @submission.problem.name,
191 @submission.id,
191 @submission.id,
192 case_num)
192 case_num)
193 if !FileTest.exists?(out_filename)
193 if !FileTest.exists?(out_filename)
194 flash[:notice] = 'Output not found.'
194 flash[:notice] = 'Output not found.'
195 redirect_to :action => 'list' and return
195 redirect_to :action => 'list' and return
196 end
196 end
197
197
198 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
198 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
199 response.headers['Content-Type'] = "application/force-download"
199 response.headers['Content-Type'] = "application/force-download"
200 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
200 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
201 response.headers["X-Sendfile"] = out_filename
201 response.headers["X-Sendfile"] = out_filename
202 response.headers['Content-length'] = File.size(out_filename)
202 response.headers['Content-length'] = File.size(out_filename)
203 render :nothing => true
203 render :nothing => true
204 else
204 else
205 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
205 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
206 end
206 end
207 end
207 end
208
208
209 def error
209 def error
210 @user = User.find(session[:user_id])
210 @user = User.find(session[:user_id])
211 end
211 end
212
212
213 # announcement refreshing and hiding methods
213 # announcement refreshing and hiding methods
214
214
215 def announcements
215 def announcements
216 if params.has_key? 'recent'
216 if params.has_key? 'recent'
217 prepare_announcements(params[:recent])
217 prepare_announcements(params[:recent])
218 else
218 else
219 prepare_announcements
219 prepare_announcements
220 end
220 end
221 render(:partial => 'announcement',
221 render(:partial => 'announcement',
222 :collection => @announcements,
222 :collection => @announcements,
223 :locals => {:announcement_effect => true})
223 :locals => {:announcement_effect => true})
224 end
224 end
225
225
226 def confirm_contest_start
226 def confirm_contest_start
227 user = User.find(session[:user_id])
227 user = User.find(session[:user_id])
228 if request.method == 'POST'
228 if request.method == 'POST'
229 user.update_start_time
229 user.update_start_time
230 redirect_to :action => 'list'
230 redirect_to :action => 'list'
231 else
231 else
232 @contests = user.contests
232 @contests = user.contests
233 @user = user
233 @user = user
234 end
234 end
235 end
235 end
236
236
237 # thailandoi contests
237 # thailandoi contests
238
238
239 def verifying_testcase
239 def verifying_testcase
240 problem = Problem.find(params[:id])
240 problem = Problem.find(params[:id])
241 if !problem.available
241 if !problem.available
242 flash[:notice] = 'Error: problem is not available'
242 flash[:notice] = 'Error: problem is not available'
243 redirect_to :action => 'list'
243 redirect_to :action => 'list'
244 else
244 else
245 test_pair = TestPair.get_for(problem, false)
245 test_pair = TestPair.get_for(problem, false)
246 send_data(test_pair.input,
246 send_data(test_pair.input,
247 {:filename => problem.name + '-verifying-input.txt',
247 {:filename => problem.name + '-verifying-input.txt',
248 :type => 'text/plain'})
248 :type => 'text/plain'})
249 end
249 end
250 end
250 end
251
251
252 def testcase
252 def testcase
253 problem = Problem.find(params[:id])
253 problem = Problem.find(params[:id])
254 if !problem.available
254 if !problem.available
255 flash[:notice] = 'Error: problem is not available'
255 flash[:notice] = 'Error: problem is not available'
256 redirect_to :action => 'list'
256 redirect_to :action => 'list'
257 else
257 else
258 test_pair = TestPair.get_for(problem, true)
258 test_pair = TestPair.get_for(problem, true)
259
259
260 user = User.find(session[:user_id])
260 user = User.find(session[:user_id])
261 assignment = user.get_test_pair_assignment_for(problem)
261 assignment = user.get_test_pair_assignment_for(problem)
262
262
263 if !assignment
263 if !assignment
264 assignment = TestPairAssignment.create_for(user, problem, test_pair)
264 assignment = TestPairAssignment.create_for(user, problem, test_pair)
265 assignment.save
265 assignment.save
266 end
266 end
267
267
268 send_data(test_pair.input,
268 send_data(test_pair.input,
269 {:filename => problem.name + '-input.txt',
269 {:filename => problem.name + '-input.txt',
270 :type => 'text/plain'})
270 :type => 'text/plain'})
271 end
271 end
272 end
272 end
273
273
274 def verifying_submit
274 def verifying_submit
275 user = User.find(session[:user_id])
275 user = User.find(session[:user_id])
276 problem_id = params[:id]
276 problem_id = params[:id]
277 problem = Problem.find(problem_id)
277 problem = Problem.find(problem_id)
278
278
279 if !problem or !problem.available
279 if !problem or !problem.available
280 flash[:notice] = 'Error: problem is not available'
280 flash[:notice] = 'Error: problem is not available'
281 redirect_to :action => 'list' and return
281 redirect_to :action => 'list' and return
282 end
282 end
283
283
284 @current_problem = problem
284 @current_problem = problem
285 test_pair = TestPair.get_for(problem, false)
285 test_pair = TestPair.get_for(problem, false)
286 if (params['output_file']) and (params['output_file']!='')
286 if (params['output_file']) and (params['output_file']!='')
287 output = params['output_file'].read
287 output = params['output_file'].read
288
288
289 - @grading_result = grade(output, test_pair.solution)
289 + @grading_result = test_pair.grade(output)
290 prepare_list_information
290 prepare_list_information
291 render :action => 'list' and return
291 render :action => 'list' and return
292 else
292 else
293 flash[:notice] = 'Error: output file errors'
293 flash[:notice] = 'Error: output file errors'
294 prepare_list_information
294 prepare_list_information
295 render :action => 'list' and return
295 render :action => 'list' and return
296 end
296 end
297 end
297 end
298
298
299 protected
299 protected
300
300
301 - def grade(output, solution)
302 - out_items = output.split("\n")
303 - sol_items = solution.split("\n")
304 - res = ''
305 - f = 0
306 - s = 0
307 - sol_items.length.times do |i|
308 - f += 1
309 - si = sol_items[i].chomp
310 - if out_items[i]
311 - oi = out_items[i].chomp
312 - else
313 - oi = ''
314 - end
315 - if oi == si
316 - res = res + 'P'
317 - s += 1
318 - else
319 - res = res + '-'
320 - end
321 - end
322 - return { :score => s, :full_score => f, :msg => res }
323 - end
324 -
325 def prepare_announcements(recent=nil)
301 def prepare_announcements(recent=nil)
326 if GraderConfiguration.show_tasks_to?(@user)
302 if GraderConfiguration.show_tasks_to?(@user)
327 @announcements = Announcement.find_published(true)
303 @announcements = Announcement.find_published(true)
328 else
304 else
329 @announcements = Announcement.find_published
305 @announcements = Announcement.find_published
330 end
306 end
331 if recent!=nil
307 if recent!=nil
332 recent_id = recent.to_i
308 recent_id = recent.to_i
333 @announcements = @announcements.find_all { |a| a.id > recent_id }
309 @announcements = @announcements.find_all { |a| a.id > recent_id }
334 end
310 end
335 end
311 end
336
312
337 def prepare_timeout_information(problems)
313 def prepare_timeout_information(problems)
338 @submission_timeouts = {}
314 @submission_timeouts = {}
339 problems.each do |problem|
315 problems.each do |problem|
340 assignment = @user.get_test_pair_assignment_for(problem)
316 assignment = @user.get_test_pair_assignment_for(problem)
341 if assignment == nil
317 if assignment == nil
342 timeout = nil
318 timeout = nil
343 else
319 else
344 if (assignment.expired?) or (assignment.submitted)
320 if (assignment.expired?) or (assignment.submitted)
345 timeout = 0
321 timeout = 0
346 else
322 else
347 timeout = assignment.created_at + TEST_ASSIGNMENT_EXPIRATION_DURATION - Time.new.gmtime
323 timeout = assignment.created_at + TEST_ASSIGNMENT_EXPIRATION_DURATION - Time.new.gmtime
348 end
324 end
349 end
325 end
350 @submission_timeouts[problem.id] = timeout
326 @submission_timeouts[problem.id] = timeout
351 end
327 end
352 end
328 end
353
329
354 def prepare_list_information
330 def prepare_list_information
355 @user = User.find(session[:user_id])
331 @user = User.find(session[:user_id])
356 if not GraderConfiguration.multicontests?
332 if not GraderConfiguration.multicontests?
357 @problems = @user.available_problems
333 @problems = @user.available_problems
358 else
334 else
359 @contest_problems = @user.available_problems_group_by_contests
335 @contest_problems = @user.available_problems_group_by_contests
360 @problems = @user.available_problems
336 @problems = @user.available_problems
361 end
337 end
362 @prob_submissions = {}
338 @prob_submissions = {}
363 @problems.each do |p|
339 @problems.each do |p|
364 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
340 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
365 if sub!=nil
341 if sub!=nil
366 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
342 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
367 else
343 else
368 @prob_submissions[p.id] = { :count => 0, :submission => nil }
344 @prob_submissions[p.id] = { :count => 0, :submission => nil }
369 end
345 end
370 end
346 end
371 prepare_announcements
347 prepare_announcements
372 prepare_timeout_information(@problems)
348 prepare_timeout_information(@problems)
373 end
349 end
374
350
375 def check_viewability
351 def check_viewability
376 @user = User.find(session[:user_id])
352 @user = User.find(session[:user_id])
377 if (!GraderConfiguration.show_tasks_to?(@user)) and
353 if (!GraderConfiguration.show_tasks_to?(@user)) and
378 ((action_name=='submission') or (action_name=='submit'))
354 ((action_name=='submission') or (action_name=='submit'))
379 redirect_to :action => 'list' and return
355 redirect_to :action => 'list' and return
380 end
356 end
381 end
357 end
382
358
383 def prepare_grading_result(submission)
359 def prepare_grading_result(submission)
384 if GraderConfiguration.task_grading_info.has_key? submission.problem.name
360 if GraderConfiguration.task_grading_info.has_key? submission.problem.name
385 grading_info = GraderConfiguration.task_grading_info[submission.problem.name]
361 grading_info = GraderConfiguration.task_grading_info[submission.problem.name]
386 else
362 else
387 # guess task info from problem.full_score
363 # guess task info from problem.full_score
388 cases = submission.problem.full_score / 10
364 cases = submission.problem.full_score / 10
389 grading_info = {
365 grading_info = {
390 'testruns' => cases,
366 'testruns' => cases,
391 'testcases' => cases
367 'testcases' => cases
392 }
368 }
393 end
369 end
394 @test_runs = []
370 @test_runs = []
395 if grading_info['testruns'].is_a? Integer
371 if grading_info['testruns'].is_a? Integer
396 trun_count = grading_info['testruns']
372 trun_count = grading_info['testruns']
397 trun_count.times do |i|
373 trun_count.times do |i|
398 @test_runs << [ read_grading_result(@user.login,
374 @test_runs << [ read_grading_result(@user.login,
399 submission.problem.name,
375 submission.problem.name,
400 submission.id,
376 submission.id,
401 i+1) ]
377 i+1) ]
402 end
378 end
403 else
379 else
404 grading_info['testruns'].keys.sort.each do |num|
380 grading_info['testruns'].keys.sort.each do |num|
405 run = []
381 run = []
406 testrun = grading_info['testruns'][num]
382 testrun = grading_info['testruns'][num]
407 testrun.each do |c|
383 testrun.each do |c|
408 run << read_grading_result(@user.login,
384 run << read_grading_result(@user.login,
409 submission.problem.name,
385 submission.problem.name,
410 submission.id,
386 submission.id,
411 c)
387 c)
412 end
388 end
413 @test_runs << run
389 @test_runs << run
414 end
390 end
415 end
391 end
416 end
392 end
417
393
418 def grading_result_dir(user_name, problem_name, submission_id, case_num)
394 def grading_result_dir(user_name, problem_name, submission_id, case_num)
419 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
395 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
420 end
396 end
421
397
422 def output_filename(user_name, problem_name, submission_id, case_num)
398 def output_filename(user_name, problem_name, submission_id, case_num)
423 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
399 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
424 return "#{dir}/output.txt"
400 return "#{dir}/output.txt"
425 end
401 end
426
402
427 def read_grading_result(user_name, problem_name, submission_id, case_num)
403 def read_grading_result(user_name, problem_name, submission_id, case_num)
428 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
404 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
429 result_file_name = "#{dir}/result"
405 result_file_name = "#{dir}/result"
430 if !FileTest.exists?(result_file_name)
406 if !FileTest.exists?(result_file_name)
431 return {:num => case_num, :msg => 'program did not run'}
407 return {:num => case_num, :msg => 'program did not run'}
432 else
408 else
433 results = File.open(result_file_name).readlines
409 results = File.open(result_file_name).readlines
434 run_stat = extract_running_stat(results)
410 run_stat = extract_running_stat(results)
435 output_filename = "#{dir}/output.txt"
411 output_filename = "#{dir}/output.txt"
436 if FileTest.exists?(output_filename)
412 if FileTest.exists?(output_filename)
437 output_file = true
413 output_file = true
438 output_size = File.size(output_filename)
414 output_size = File.size(output_filename)
439 else
415 else
440 output_file = false
416 output_file = false
441 output_size = 0
417 output_size = 0
442 end
418 end
443
419
444 return {
420 return {
445 :num => case_num,
421 :num => case_num,
446 :msg => results[0],
422 :msg => results[0],
447 :run_stat => run_stat,
423 :run_stat => run_stat,
448 :output => output_file,
424 :output => output_file,
449 :output_size => output_size
425 :output_size => output_size
450 }
426 }
451 end
427 end
452 end
428 end
453
429
454 # copied from grader/script/lib/test_request_helper.rb
430 # copied from grader/script/lib/test_request_helper.rb
455 def extract_running_stat(results)
431 def extract_running_stat(results)
456 running_stat_line = results[-1]
432 running_stat_line = results[-1]
457
433
458 # extract exit status line
434 # extract exit status line
459 run_stat = ""
435 run_stat = ""
460 if !(/[Cc]orrect/.match(results[0]))
436 if !(/[Cc]orrect/.match(results[0]))
461 run_stat = results[0].chomp
437 run_stat = results[0].chomp
462 else
438 else
463 run_stat = 'Program exited normally'
439 run_stat = 'Program exited normally'
464 end
440 end
465
441
466 logger.info "Stat line: #{running_stat_line}"
442 logger.info "Stat line: #{running_stat_line}"
467
443
468 # extract running time
444 # extract running time
469 if res = /r(.*)u(.*)s/.match(running_stat_line)
445 if res = /r(.*)u(.*)s/.match(running_stat_line)
470 seconds = (res[1].to_f + res[2].to_f)
446 seconds = (res[1].to_f + res[2].to_f)
471 time_stat = "Time used: #{seconds} sec."
447 time_stat = "Time used: #{seconds} sec."
472 else
448 else
473 seconds = nil
449 seconds = nil
474 time_stat = "Time used: n/a sec."
450 time_stat = "Time used: n/a sec."
475 end
451 end
476
452
477 # extract memory usage
453 # extract memory usage
478 if res = /s(.*)m/.match(running_stat_line)
454 if res = /s(.*)m/.match(running_stat_line)
479 memory_used = res[1].to_i
455 memory_used = res[1].to_i
480 else
456 else
481 memory_used = -1
457 memory_used = -1
482 end
458 end
483
459
484 return {
460 return {
485 :msg => "#{run_stat}\n#{time_stat}",
461 :msg => "#{run_stat}\n#{time_stat}",
486 :running_time => seconds,
462 :running_time => seconds,
487 :exit_status => run_stat,
463 :exit_status => run_stat,
488 :memory_usage => memory_used
464 :memory_usage => memory_used
489 }
465 }
490 end
466 end
491
467
492 def confirm_and_update_start_time
468 def confirm_and_update_start_time
493 user = User.find(session[:user_id])
469 user = User.find(session[:user_id])
494 if (GraderConfiguration.indv_contest_mode? and
470 if (GraderConfiguration.indv_contest_mode? and
495 GraderConfiguration['contest.confirm_indv_contest_start'] and
471 GraderConfiguration['contest.confirm_indv_contest_start'] and
496 !user.contest_started?)
472 !user.contest_started?)
497 redirect_to :action => 'confirm_contest_start' and return
473 redirect_to :action => 'confirm_contest_start' and return
498 end
474 end
499 if not GraderConfiguration.analysis_mode?
475 if not GraderConfiguration.analysis_mode?
500 user.update_start_time
476 user.update_start_time
501 end
477 end
502 end
478 end
503
479
504 def reject_announcement_refresh_when_logged_out
480 def reject_announcement_refresh_when_logged_out
505 if not session[:user_id]
481 if not session[:user_id]
506 render :text => 'Access forbidden', :status => 403
482 render :text => 'Access forbidden', :status => 403
507 end
483 end
508
484
509 if GraderConfiguration.multicontests?
485 if GraderConfiguration.multicontests?
510 user = User.find(session[:user_id])
486 user = User.find(session[:user_id])
511 if user.contest_stat.forced_logout
487 if user.contest_stat.forced_logout
512 render :text => 'Access forbidden', :status => 403
488 render :text => 'Access forbidden', :status => 403
513 end
489 end
514 end
490 end
515 end
491 end
516
492
@@ -1,8 +1,33
1 class TestPair < ActiveRecord::Base
1 class TestPair < ActiveRecord::Base
2 belongs_to :problem
2 belongs_to :problem
3
3
4 def self.get_for(problem, is_private)
4 def self.get_for(problem, is_private)
5 return TestPair.where(:problem_id => problem.id,
5 return TestPair.where(:problem_id => problem.id,
6 :is_private => is_private).first
6 :is_private => is_private).first
7 end
7 end
8 +
9 + def grade(output)
10 + out_items = output.split("\n")
11 + sol_items = solution.split("\n")
12 + res = ''
13 + f = 0
14 + s = 0
15 + sol_items.length.times do |i|
16 + f += 1
17 + si = sol_items[i].chomp
18 + if out_items[i]
19 + oi = out_items[i].chomp
20 + else
21 + oi = ''
22 + end
23 + if oi == si
24 + res = res + 'P'
25 + s += 1
26 + else
27 + res = res + '-'
28 + end
29 + end
30 + return { :score => s, :full_score => f, :msg => res }
31 + end
32 +
8 end
33 end
You need to be logged in to leave comments. Login now