-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathcheck_similar
executable file
·93 lines (74 loc) · 2.16 KB
/
check_similar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/env ruby
def config
Grader::Configuration.get_instance
end
def display_manual
puts <<USAGE
Check similarity between submission
using: check_similar sub1 sub2
-- or --
check_similar problem_name
sub1 and sub2 are submission IDs to be checked
problem_name will check all submissions of the problem wit problem short name is 'problem_name'
The output are given as
sub1.login, sub1.id, sub1.point, sub2.login, sub2.id, sub2.point, similarity
USAGE
end
def process_options_and_stop_file
# Process 'help' option
if (ARGV.length == 0) or ((ARGV.length==1) and (/help/.match(ARGV[0])))
display_manual
exit(0)
end
#default options
options = {
:dry_run => false,
}
if ARGV.length == 2
options[:sub1] = ARGV[0].to_i
options[:sub2] = ARGV[1].to_i
elsif ARGV.length == 1
options[:problem] = ARGV[0]
end
return options
end
def compare(sub1,sub2,full = sub1.problem.full_score)
dis = @jarow.getDistance(sub1.source, sub2.source)
puts [sub1.user.login,"##{sub1.id}",(sub1.points * 100.0 / full).to_i,
sub2.user.login,"##{sub2.id}",(sub2.points * 100.0 / full).to_i,
"#{dis * 100}%"].join(',')
end
#########################################
# main program
#########################################
options = process_options_and_stop_file
# load grader environment
GRADER_ENV = 'grading'
require File.join(File.dirname(__FILE__),'config/environment')
# boot rails, to be able to use the active record
RAILS_ENV = config.rails_env
require RAILS_ROOT + '/config/environment'
# load comparator
require 'fuzzystringmatch'
@jarow = FuzzyStringMatch::JaroWinkler.create( :native )
if options[:problem]
p = Problem.where(name: options[:problem]).first
unless p
puts "cannot find problem #{options[:problem]}"
exit(0)
end
subs = Submission.where(problem: p)
full_score = p.full_score.to_i
subs.each.with_index do |s1,i|
puts "processing #{i+1} out of #{subs.length}"
subs.each do |s2|
if s1.user != s2.user
compare(s1,s2,full_score)
end
end
end
else
sub1 = Submission.find(options[:sub1])
sub2 = Submission.find(options[:sub2])
compare(sub1,sub2)
end