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

r241:19abb7c667e3 - - 7 files changed: 124 inserted, 4 deleted

@@ -0,0 +1,93
1 + #!/usr/bin/env ruby
2 +
3 + def config
4 + Grader::Configuration.get_instance
5 + end
6 +
7 + def display_manual
8 + puts <<USAGE
9 + Check similarity between submission
10 + using: check_similar sub1 sub2
11 + -- or --
12 + check_similar problem_name
13 + sub1 and sub2 are submission IDs to be checked
14 + problem_name will check all submissions of the problem wit problem short name is 'problem_name'
15 +
16 + The output are given as
17 + sub1.login, sub1.id, sub1.point, sub2.login, sub2.id, sub2.point, similarity
18 +
19 + USAGE
20 + end
21 +
22 + def process_options_and_stop_file
23 +
24 + # Process 'help' option
25 + if (ARGV.length == 0) or ((ARGV.length==1) and (/help/.match(ARGV[0])))
26 + display_manual
27 + exit(0)
28 + end
29 +
30 + #default options
31 + options = {
32 + :dry_run => false,
33 + }
34 +
35 +
36 + if ARGV.length == 2
37 + options[:sub1] = ARGV[0].to_i
38 + options[:sub2] = ARGV[1].to_i
39 + elsif ARGV.length == 1
40 + options[:problem] = ARGV[0]
41 + end
42 +
43 +
44 + return options
45 + end
46 +
47 + def compare(sub1,sub2,full = sub1.problem.full_score)
48 + dis = @jarow.getDistance(sub1.source, sub2.source)
49 + puts [sub1.user.login,"##{sub1.id}",(sub1.points * 100.0 / full).to_i,
50 + sub2.user.login,"##{sub2.id}",(sub2.points * 100.0 / full).to_i,
51 + "#{dis * 100}%"].join(',')
52 + end
53 +
54 + #########################################
55 + # main program
56 + #########################################
57 +
58 + options = process_options_and_stop_file
59 +
60 + # load grader environment
61 + GRADER_ENV = 'grading'
62 + require File.join(File.dirname(__FILE__),'config/environment')
63 +
64 + # boot rails, to be able to use the active record
65 + RAILS_ENV = config.rails_env
66 + require RAILS_ROOT + '/config/environment'
67 +
68 + # load comparator
69 + require 'fuzzystringmatch'
70 + @jarow = FuzzyStringMatch::JaroWinkler.create( :native )
71 +
72 + if options[:problem]
73 + p = Problem.where(name: options[:problem]).first
74 + unless p
75 + puts "cannot find problem #{options[:problem]}"
76 + exit(0)
77 + end
78 + subs = Submission.where(problem: p)
79 + full_score = p.full_score.to_i
80 + subs.each.with_index do |s1,i|
81 + puts "processing #{i+1} out of #{subs.length}"
82 + subs.each do |s2|
83 + if s1.user != s2.user
84 + compare(s1,s2,full_score)
85 + end
86 + end
87 + end
88 + else
89 + sub1 = Submission.find(options[:sub1])
90 + sub2 = Submission.find(options[:sub2])
91 + compare(sub1,sub2)
92 + end
93 +
@@ -0,0 +1,6
1 + #!/bin/bash
2 + count=`ps aux | grep "cafe_grader" | grep "grader grading queue" | wc -l`
3 + if [ $count -lt 1 ]; then
4 + cd /home/dae/cafe_grader/judge
5 + /home/dae/.rvm/wrappers/ruby-2.3.0/ruby /home/dae/cafe_grader/judge/scripts/grader grading queue > /home/dae/grading.log &
6 + fi
@@ -136,24 +136,30
136 testrun.each do |testcase_info|
136 testrun.each do |testcase_info|
137 testcase_num, testcase_fname = testcase_info
137 testcase_num, testcase_fname = testcase_info
138
138
139 puts "copy #{testcase_fname} to #{testcase_num}"
139 puts "copy #{testcase_fname} to #{testcase_num}"
140
140
141 create_dir_if_not_exists("#{problem_dir}/test_cases/#{testcase_num}")
141 create_dir_if_not_exists("#{problem_dir}/test_cases/#{testcase_num}")
142 copy_testcase("#{testcase_dir}",testcase_fname,"#{problem_dir}/test_cases/#{testcase_num}",testcase_num)
142 copy_testcase("#{testcase_dir}",testcase_fname,"#{problem_dir}/test_cases/#{testcase_num}",testcase_num)
143
143
144 num_testcases += 1
144 num_testcases += 1
145 end
145 end
146 end
146 end
147
147
148 + #also include any .txt files
149 + Dir.glob("#{testcase_dir}/*.txt") do |file|
150 + puts "copy data file #{file}"
151 + FileUtils.cp(file,"#{problem_dir}")
152 + end
153 +
148 # generating all_tests.cfg
154 # generating all_tests.cfg
149 puts "generating testcase config file"
155 puts "generating testcase config file"
150
156
151 template = File.open(SCRIPT_DIR + "/templates/all_tests.cfg.erb").read
157 template = File.open(SCRIPT_DIR + "/templates/all_tests.cfg.erb").read
152 all_test_cfg = ERB.new(template)
158 all_test_cfg = ERB.new(template)
153
159
154 cfg_file = File.open("#{problem_dir}/test_cases/all_tests.cfg","w")
160 cfg_file = File.open("#{problem_dir}/test_cases/all_tests.cfg","w")
155 cfg_file.puts all_test_cfg.result binding
161 cfg_file.puts all_test_cfg.result binding
156 cfg_file.close
162 cfg_file.close
157
163
158 # copy check script
164 # copy check script
159 if res = /^wrapper:(.*)$/.match(check_script)
165 if res = /^wrapper:(.*)$/.match(check_script)
@@ -11,25 +11,25
11 problem_name are list of "short name" of the problems
11 problem_name are list of "short name" of the problems
12
12
13 options:
13 options:
14 --dry-run do nothing, just simulate the run
14 --dry-run do nothing, just simulate the run
15 --all import all problem. This might take several minutes
15 --all import all problem. This might take several minutes
16
16
17 USAGE
17 USAGE
18 end
18 end
19
19
20 def process_options_and_stop_file
20 def process_options_and_stop_file
21
21
22 # Process 'help' option
22 # Process 'help' option
23 - if (ARGV.length==1) and (/help/.match(ARGV[0]))
23 + if (ARGV.length == 0) or ((ARGV.length==1) and (/help/.match(ARGV[0])))
24 display_manual
24 display_manual
25 exit(0)
25 exit(0)
26 end
26 end
27
27
28 #default options
28 #default options
29 options = {
29 options = {
30 :dry_run => false,
30 :dry_run => false,
31 }
31 }
32
32
33 options[:dry_run] = (ARGV.delete('--dry') != nil)
33 options[:dry_run] = (ARGV.delete('--dry') != nil)
34 options[:all] = (ARGV.delete('--all') != nil)
34 options[:all] = (ARGV.delete('--all') != nil)
35
35
@@ -65,21 +65,21
65
65
66 options = process_options_and_stop_file
66 options = process_options_and_stop_file
67
67
68 # load grader environment
68 # load grader environment
69 GRADER_ENV = 'grading'
69 GRADER_ENV = 'grading'
70 require File.join(File.dirname(__FILE__),'config/environment')
70 require File.join(File.dirname(__FILE__),'config/environment')
71
71
72 # boot rails, to be able to use the active record
72 # boot rails, to be able to use the active record
73 RAILS_ENV = config.rails_env
73 RAILS_ENV = config.rails_env
74 require RAILS_ROOT + '/config/environment'
74 require RAILS_ROOT + '/config/environment'
75
75
76 if options[:all]
76 if options[:all]
77 - Problem.all.each { |prob| process_problem(prob,options[:all]) }
77 + Problem.all.each { |prob| process_problem(prob,options[:dry_run]) }
78 else
78 else
79 ARGV.each do |name|
79 ARGV.each do |name|
80 prob = Problem.find_by(name: name)
80 prob = Problem.find_by(name: name)
81 process_problem(prob,options[:dry_run]) if prob
81 process_problem(prob,options[:dry_run]) if prob
82 puts "Cannot find the problem #{name}" unless prob
82 puts "Cannot find the problem #{name}" unless prob
83 end
83 end
84 end
84 end
85
85
@@ -1,23 +1,23
1 #!/usr/bin/env ruby
1 #!/usr/bin/env ruby
2
2
3 ENVIRONMENT_DIRS = ['ev', 'ev-exam']
3 ENVIRONMENT_DIRS = ['ev', 'ev-exam']
4
4
5 def config
5 def config
6 Grader::Configuration.get_instance
6 Grader::Configuration.get_instance
7 end
7 end
8
8
9 def rename_problem(old_problem_name, new_problem_name)
9 def rename_problem(old_problem_name, new_problem_name)
10
10
11 - if valid_problem_name(new_problem_name)
11 + unless valid_problem_name(new_problem_name)
12 puts "Bad new problem name: #{new_problem_name}"
12 puts "Bad new problem name: #{new_problem_name}"
13 return
13 return
14 end
14 end
15
15
16 problem = Problem.find_by_name(old_problem_name)
16 problem = Problem.find_by_name(old_problem_name)
17 if problem==nil
17 if problem==nil
18 puts "Problem #{old_problem_name} does not exist."
18 puts "Problem #{old_problem_name} does not exist."
19 return
19 return
20 end
20 end
21
21
22 puts "Problem: #{old_problem_name} -> #{new_problem_name}"
22 puts "Problem: #{old_problem_name} -> #{new_problem_name}"
23
23
@@ -51,25 +51,25
51 When using with -f, that file should contain, for each line, the old
51 When using with -f, that file should contain, for each line, the old
52 problem name and its new name.
52 problem name and its new name.
53
53
54 This script should be called at the judge root dir where dirs 'ev' and
54 This script should be called at the judge root dir where dirs 'ev' and
55 'ev-exam' are.
55 'ev-exam' are.
56 USAGE
56 USAGE
57 end
57 end
58
58
59 def valid_problem_name(name)
59 def valid_problem_name(name)
60 if name.length==0:
60 if name.length==0:
61 return false
61 return false
62 else
62 else
63 - return !(/^[a-zA-Z0-9_\-]+$/ === name)
63 + return (/^[a-zA-Z0-9_\-]+$/ === name)
64 end
64 end
65 end
65 end
66
66
67 if (ARGV.length!=2)
67 if (ARGV.length!=2)
68 usage
68 usage
69 exit(0)
69 exit(0)
70 end
70 end
71
71
72 if ARGV[0]=='-f' and !FileTest.exists?(ARGV[1])
72 if ARGV[0]=='-f' and !FileTest.exists?(ARGV[1])
73 puts "File #{ARGV[1]} does not exist."
73 puts "File #{ARGV[1]} does not exist."
74 usage
74 usage
75 exit(0)
75 exit(0)
@@ -131,24 +131,30
131
131
132 $stdout.print "[#{test_num}]"
132 $stdout.print "[#{test_num}]"
133 $stdout.flush
133 $stdout.flush
134
134
135 log "Test number: #{test_num}"
135 log "Test number: #{test_num}"
136
136
137 call_and_log("Cannot copy the compiled program into #{sandbox_dir}") {
137 call_and_log("Cannot copy the compiled program into #{sandbox_dir}") {
138 FileUtils.cp("#{test_result_dir}/a.out", sandbox_dir, :preserve => true)
138 FileUtils.cp("#{test_result_dir}/a.out", sandbox_dir, :preserve => true)
139 if language == "java" then Dir["#{test_result_dir}/*.class"].each { |file| FileUtils.cp(file,sandbox_dir)} end
139 if language == "java" then Dir["#{test_result_dir}/*.class"].each { |file| FileUtils.cp(file,sandbox_dir)} end
140 if language == "python" then Dir["#{test_result_dir}/*.pyc"].each { |file| FileUtils.cp(file,sandbox_dir)} end
140 if language == "python" then Dir["#{test_result_dir}/*.pyc"].each { |file| FileUtils.cp(file,sandbox_dir)} end
141 }
141 }
142
142
143 + #additionally copy any extra .txt file
144 + data_files = Dir[problem_home + '/*.txt']
145 + data_files.each do |file|
146 + FileUtils.cp(file,sandbox_dir)
147 + end
148 +
143 begin
149 begin
144 execute("#{problem_home}/script/run #{language} #{test_num} ", "Error occured during execution of the run script")
150 execute("#{problem_home}/script/run #{language} #{test_num} ", "Error occured during execution of the run script")
145 rescue
151 rescue
146 # do nothing
152 # do nothing
147 end
153 end
148
154
149 call_and_log("Cannot create directory #{test_result_dir}/#{test_num}") {
155 call_and_log("Cannot create directory #{test_result_dir}/#{test_num}") {
150 FileUtils.mkdir "#{test_result_dir}/#{test_num}"
156 FileUtils.mkdir "#{test_result_dir}/#{test_num}"
151 }
157 }
152 call_and_log("Cannot copy the result file into #{test_result_dir}/#{test_num}") {
158 call_and_log("Cannot copy the result file into #{test_result_dir}/#{test_num}") {
153 FileUtils.mv "#{sandbox_dir}/result", "#{test_result_dir}/#{test_num}"
159 FileUtils.mv "#{sandbox_dir}/result", "#{test_result_dir}/#{test_num}"
154 }
160 }
@@ -38,29 +38,38
38 result_file.write "Incorrect\n"
38 result_file.write "Incorrect\n"
39 result_file.write "0\n"
39 result_file.write "0\n"
40 result_file.close
40 result_file.close
41 exit(0)
41 exit(0)
42 }
42 }
43
43
44 ##################
44 ##################
45 # Your code here #
45 # Your code here #
46 ##################
46 ##################
47
47
48 ########### THIS IS FOR CHECKING FLOAT with EPSILON error ##########
48 ########### THIS IS FOR CHECKING FLOAT with EPSILON error ##########
49
49
50 +
51 + def is_float?(fl)
52 + !!Float(fl) rescue false
53 + end
54 +
50 EPSILON = 0.000001
55 EPSILON = 0.000001
51
56
52 out_items = output_file_content.split
57 out_items = output_file_content.split
53 ans_items = answer_file_content.split
58 ans_items = answer_file_content.split
54
59
55 if out_items.length != ans_items.length
60 if out_items.length != ans_items.length
56 report_wrong.call
61 report_wrong.call
57 else
62 else
58 out_items.length.times do |i|
63 out_items.length.times do |i|
64 + if is_float?(out_items[i]) && is_float?(ans_items[i])
59 out_value = out_items[i].to_f
65 out_value = out_items[i].to_f
60 ans_value = ans_items[i].to_f
66 ans_value = ans_items[i].to_f
61 if (out_value - ans_value).abs > EPSILON * [out_value.abs,ans_value.abs].max
67 if (out_value - ans_value).abs > EPSILON * [out_value.abs,ans_value.abs].max
62 report_wrong.call
68 report_wrong.call
63 end
69 end
70 + else
71 + report_wrong.call if out_items[i] != ans_items[i]
72 + end
64 end
73 end
65 report_correct.call
74 report_correct.call
66 end
75 end
You need to be logged in to leave comments. Login now