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
@@ -241,132 +241,108
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)
@@ -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