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: 128 inserted, 8 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
@@ -124,48 +124,54
124 124 create_dir_if_not_exists("#{problem_dir}/test_cases")
125 125
126 126 puts "copying testcases"
127 127
128 128 tr_num = 0
129 129
130 130 num_testcases = 0
131 131
132 132 testrun_info.each do |testrun|
133 133 tr_num += 1
134 134 puts "testrun: #{tr_num}"
135 135
136 136 testrun.each do |testcase_info|
137 137 testcase_num, testcase_fname = testcase_info
138 138
139 139 puts "copy #{testcase_fname} to #{testcase_num}"
140 140
141 141 create_dir_if_not_exists("#{problem_dir}/test_cases/#{testcase_num}")
142 142 copy_testcase("#{testcase_dir}",testcase_fname,"#{problem_dir}/test_cases/#{testcase_num}",testcase_num)
143 143
144 144 num_testcases += 1
145 145 end
146 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 154 # generating all_tests.cfg
149 155 puts "generating testcase config file"
150 156
151 157 template = File.open(SCRIPT_DIR + "/templates/all_tests.cfg.erb").read
152 158 all_test_cfg = ERB.new(template)
153 159
154 160 cfg_file = File.open("#{problem_dir}/test_cases/all_tests.cfg","w")
155 161 cfg_file.puts all_test_cfg.result binding
156 162 cfg_file.close
157 163
158 164 # copy check script
159 165 if res = /^wrapper:(.*)$/.match(check_script)
160 166 # wrapper script
161 167 check_script_fname = res[1]
162 168 script_name = File.basename(check_script_fname)
163 169 check_wrapper_template = File.open(SCRIPT_DIR + "/templates/check_wrapper").read
164 170 check_wrapper = ERB.new(check_wrapper_template)
165 171
166 172 check_file = File.open("#{problem_dir}/script/check","w")
167 173 check_file.puts check_wrapper.result binding
168 174 check_file.close
169 175
170 176 File.chmod(0755,"#{problem_dir}/script/check")
171 177
@@ -1,47 +1,47
1 1 #!/usr/bin/env ruby
2 2
3 3 def config
4 4 Grader::Configuration.get_instance
5 5 end
6 6
7 7 def display_manual
8 8 puts <<USAGE
9 9 load_testcases
10 10 using: load_testcases [problem_name ...]
11 11 problem_name are list of "short name" of the problems
12 12
13 13 options:
14 14 --dry-run do nothing, just simulate the run
15 15 --all import all problem. This might take several minutes
16 16
17 17 USAGE
18 18 end
19 19
20 20 def process_options_and_stop_file
21 21
22 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 24 display_manual
25 25 exit(0)
26 26 end
27 27
28 28 #default options
29 29 options = {
30 30 :dry_run => false,
31 31 }
32 32
33 33 options[:dry_run] = (ARGV.delete('--dry') != nil)
34 34 options[:all] = (ARGV.delete('--all') != nil)
35 35
36 36 return options
37 37 end
38 38
39 39 def process_problem(prob,dry_run = false)
40 40 prob.testcases.destroy_all
41 41 testcases_root = File.expand_path(GRADER_ROOT+"/../ev/#{prob.name}/test_cases/")
42 42 num = 1
43 43 puts "Processing problem #{prob.name}"
44 44 loop do
45 45 file_root = testcases_root + "/#{num}/"
46 46 puts " checking file #{file_root}"
47 47 break unless File.exists? file_root
@@ -53,33 +53,33
53 53 group = num #this is wrong!!! fix it!!
54 54 score = 10
55 55 #BEWARE
56 56
57 57 prob.testcases.create(input: input,sol: answer, num: num, score:score,group: group) unless dry_run
58 58 num += 1
59 59 end
60 60 end
61 61
62 62 #########################################
63 63 # main program
64 64 #########################################
65 65
66 66 options = process_options_and_stop_file
67 67
68 68 # load grader environment
69 69 GRADER_ENV = 'grading'
70 70 require File.join(File.dirname(__FILE__),'config/environment')
71 71
72 72 # boot rails, to be able to use the active record
73 73 RAILS_ENV = config.rails_env
74 74 require RAILS_ROOT + '/config/environment'
75 75
76 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 78 else
79 79 ARGV.each do |name|
80 80 prob = Problem.find_by(name: name)
81 81 process_problem(prob,options[:dry_run]) if prob
82 82 puts "Cannot find the problem #{name}" unless prob
83 83 end
84 84 end
85 85
@@ -1,35 +1,35
1 1 #!/usr/bin/env ruby
2 2
3 3 ENVIRONMENT_DIRS = ['ev', 'ev-exam']
4 4
5 5 def config
6 6 Grader::Configuration.get_instance
7 7 end
8 8
9 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 12 puts "Bad new problem name: #{new_problem_name}"
13 13 return
14 14 end
15 15
16 16 problem = Problem.find_by_name(old_problem_name)
17 17 if problem==nil
18 18 puts "Problem #{old_problem_name} does not exist."
19 19 return
20 20 end
21 21
22 22 puts "Problem: #{old_problem_name} -> #{new_problem_name}"
23 23
24 24 ENVIRONMENT_DIRS.each do |dir|
25 25 problem_dir = File.join(GRADER_ROOT,'..',dir,old_problem_name)
26 26 new_problem_dir = File.join(GRADER_ROOT,'..',dir,new_problem_name)
27 27
28 28 if FileTest.exists? problem_dir
29 29 puts "Moving #{problem_dir} to #{new_problem_dir}."
30 30 File.rename(problem_dir, new_problem_dir)
31 31
32 32 tr_problem_dir = File.join(GRADER_ROOT,'..',dir,
33 33 'test_request',old_problem_name)
34 34 new_tr_problem_dir = File.join(GRADER_ROOT,'..',dir,
35 35 'test_request',new_problem_name)
@@ -39,49 +39,49
39 39
40 40 problem.name = new_problem_name
41 41 problem.save
42 42 end
43 43
44 44 def usage
45 45 puts <<USAGE
46 46 Usage:
47 47 rename_problem [old_name] [new_name]
48 48 or
49 49 rename_problem -f [filename]
50 50
51 51 When using with -f, that file should contain, for each line, the old
52 52 problem name and its new name.
53 53
54 54 This script should be called at the judge root dir where dirs 'ev' and
55 55 'ev-exam' are.
56 56 USAGE
57 57 end
58 58
59 59 def valid_problem_name(name)
60 60 if name.length==0:
61 61 return false
62 62 else
63 - return !(/^[a-zA-Z0-9_\-]+$/ === name)
63 + return (/^[a-zA-Z0-9_\-]+$/ === name)
64 64 end
65 65 end
66 66
67 67 if (ARGV.length!=2)
68 68 usage
69 69 exit(0)
70 70 end
71 71
72 72 if ARGV[0]=='-f' and !FileTest.exists?(ARGV[1])
73 73 puts "File #{ARGV[1]} does not exist."
74 74 usage
75 75 exit(0)
76 76 end
77 77
78 78 # load grader environment
79 79 GRADER_ENV = 'grading'
80 80 require File.join(File.dirname(__FILE__),'config/environment')
81 81
82 82 # boot rails, to be able to rename the problem
83 83 RAILS_ENV = config.rails_env
84 84 require RAILS_ROOT + '/config/environment'
85 85
86 86 if ARGV[0]!='-f'
87 87 old_problem_name = ARGV[0]
@@ -119,48 +119,54
119 119
120 120 require "#{problem_home}/script/test_dsl.rb"
121 121 load "#{problem_home}/test_cases/all_tests.cfg"
122 122 problem = Problem.get_instance
123 123
124 124 if problem.well_formed? == false
125 125 log "The problem specification is not well formed."
126 126 exit(127)
127 127 end
128 128
129 129 # Doing the testing.
130 130 (1..(problem.num_tests)).each do |test_num|
131 131
132 132 $stdout.print "[#{test_num}]"
133 133 $stdout.flush
134 134
135 135 log "Test number: #{test_num}"
136 136
137 137 call_and_log("Cannot copy the compiled program into #{sandbox_dir}") {
138 138 FileUtils.cp("#{test_result_dir}/a.out", sandbox_dir, :preserve => true)
139 139 if language == "java" then Dir["#{test_result_dir}/*.class"].each { |file| FileUtils.cp(file,sandbox_dir)} end
140 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 149 begin
144 150 execute("#{problem_home}/script/run #{language} #{test_num} ", "Error occured during execution of the run script")
145 151 rescue
146 152 # do nothing
147 153 end
148 154
149 155 call_and_log("Cannot create directory #{test_result_dir}/#{test_num}") {
150 156 FileUtils.mkdir "#{test_result_dir}/#{test_num}"
151 157 }
152 158 call_and_log("Cannot copy the result file into #{test_result_dir}/#{test_num}") {
153 159 FileUtils.mv "#{sandbox_dir}/result", "#{test_result_dir}/#{test_num}"
154 160 }
155 161 call_and_log("Cannot copy the comment file into #{test_result_dir}/#{test_num}") {
156 162 FileUtils.mv "#{sandbox_dir}/comment", "#{test_result_dir}/#{test_num}"
157 163 }
158 164 call_and_log("Cannot copy the output file into #{test_result_dir}/#{test_num}") {
159 165 FileUtils.mv "#{sandbox_dir}/output.txt", "#{test_result_dir}/#{test_num}"
160 166 }
161 167 call_and_log("Cannot clear #{sandbox_dir}") {
162 168 FileUtils.rm_rf(Dir.glob("#{sandbox_dir}/*"), :secure => true)
163 169 }
164 170 end
165 171
166 172 $stdout.print "[done]\n"
@@ -26,41 +26,50
26 26 output_file_content = output_file.read
27 27 answer_file_content = answer_file.read
28 28
29 29 report_correct = lambda {
30 30 result_file.write "Correct\n"
31 31 result_file.write problem.get_score(test_num)
32 32 result_file.write "\n"
33 33 result_file.close
34 34 exit(0)
35 35 }
36 36
37 37 report_wrong = lambda {
38 38 result_file.write "Incorrect\n"
39 39 result_file.write "0\n"
40 40 result_file.close
41 41 exit(0)
42 42 }
43 43
44 44 ##################
45 45 # Your code here #
46 46 ##################
47 47
48 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 55 EPSILON = 0.000001
51 56
52 57 out_items = output_file_content.split
53 58 ans_items = answer_file_content.split
54 59
55 60 if out_items.length != ans_items.length
56 61 report_wrong.call
57 62 else
58 63 out_items.length.times do |i|
59 - out_value = out_items[i].to_f
60 - ans_value = ans_items[i].to_f
61 - if (out_value - ans_value).abs > EPSILON * [out_value.abs,ans_value.abs].max
62 - report_wrong.call
64 + if is_float?(out_items[i]) && is_float?(ans_items[i])
65 + out_value = out_items[i].to_f
66 + ans_value = ans_items[i].to_f
67 + if (out_value - ans_value).abs > EPSILON * [out_value.abs,ans_value.abs].max
68 + report_wrong.call
69 + end
70 + else
71 + report_wrong.call if out_items[i] != ans_items[i]
63 72 end
64 73 end
65 74 report_correct.call
66 75 end
You need to be logged in to leave comments. Login now