Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement grading #17

Merged
merged 33 commits into from
Oct 26, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
3757172
Grade improvements.
MLLeKander Oct 25, 2013
68d7452
cpc.rb: Add end statement at bottom of file.
Oct 25, 2013
8074878
Add end to contest_dir
coyotebush Oct 25, 2013
aa8724a
Grades... grades everywhere.
MLLeKander Oct 26, 2013
befc42b
Merge in master.
MLLeKander Oct 26, 2013
3881044
Consistent spacing
frewsxcv Oct 26, 2013
bbb73da
Merge branch 'dev_michael' of github.com:CPLUG/cpc into dev_michael
frewsxcv Oct 26, 2013
fe4eaf9
move_submission
MLLeKander Oct 26, 2013
0c3dea1
Merge branch 'dev_michael' of github.com:CPLUG/cpc into dev_michael
MLLeKander Oct 26, 2013
437a49d
More spacing issues.
MLLeKander Oct 26, 2013
15f476e
Initial commit of compile/run
frewsxcv Oct 26, 2013
5d312f9
Grade should return true
frewsxcv Oct 26, 2013
b56e71b
If user is not an admin, don't grade
frewsxcv Oct 26, 2013
d62c7bd
Remove unnecessary 'return'
frewsxcv Oct 26, 2013
15bcea2
problem_list returns just the names of problems instead of their paths
frewsxcv Oct 26, 2013
6eb7702
Remove pathname library dependency
frewsxcv Oct 26, 2013
152ef9c
More consistent naming scheme
frewsxcv Oct 26, 2013
1efcf5e
Fix indentation
frewsxcv Oct 26, 2013
b10e76a
Clean up code
frewsxcv Oct 26, 2013
2d6fd4a
Remove unnecessary debugging puts
frewsxcv Oct 26, 2013
6b439f7
Fix submitted file path
frewsxcv Oct 26, 2013
44e74af
Implement compiling
frewsxcv Oct 26, 2013
43baa6a
Implement running
frewsxcv Oct 26, 2013
f6772c7
Consistent var names, pass in file path instead of submission
frewsxcv Oct 26, 2013
e5d8dfe
Implement diffing against expected result
frewsxcv Oct 26, 2013
2bd5aab
Fix Problems command not printing out the problem
frewsxcv Oct 26, 2013
cfb8b09
Fix output filename being incorrect
frewsxcv Oct 26, 2013
2791095
Print whether they passed the test cases
frewsxcv Oct 26, 2013
3a0da8b
Print more user friendly output
frewsxcv Oct 26, 2013
78e20ca
Fix move_submission
frewsxcv Oct 26, 2013
207cfdb
Fix shadowing error
frewsxcv Oct 26, 2013
0975f64
Fix var reference
frewsxcv Oct 26, 2013
fae4b5f
if there's no out file, fail
frewsxcv Oct 26, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config.rb.sample
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ $fancycat_loc = '/home/michael/cpc/fancyCat'
$default_contest = 'W12'

# Login names of admins that are able to run `cpc grade`
$admin_users = ['mlekande']
$admin_users = ['mlekande','csc-cplug']
119 changes: 108 additions & 11 deletions src/cpc.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#!/usr/bin/env ruby
#change to #!/home/pfaiman/ruby/bin/ruby to prevent tampering with runtime

require 'pathname'
require 'getoptlong'
require 'sqlite3'
require 'date'
Expand Down Expand Up @@ -53,11 +52,22 @@
"Usage: cpc help [command]\n" + $commands_summary
}

def contest_dir(contest=default_contest)
File.join($problem_loc, contest)
end

def problem_dir(problem)
File.join($problem_loc, $default_contest, problem)
end

def submission_dir(problem, user)
def problem_list(contest=$default_contest)
contests_paths = File.join(contest_dir(contest), "*")
Dir[contests_paths].map do |contest_abs_path|
File.basename(contest_abs_path)
end
end

def submission_dir(problem, user="")
File.join(problem_dir(problem), "submissions", "queued", user)
end

Expand Down Expand Up @@ -125,16 +135,105 @@ def scoreboard(user, args)
false
end

def compile(file_path)
dirname = File.dirname(file_path)
filename = File.basename(file_path)
fileext = File.extname(file_path)

command = {
".c" => "gcc #{filename}",
".cpp" => "g++ #{filename}",
".java" => "javac #{filename}",
".sh" => "chmod +x #{filename}",
}[fileext]

if command
system("cd #{dirname} && #{command}")
end

true
end

def run(file_path, in_file_path)
dirname = File.dirname(file_path)
fileext = File.extname(file_path)
basename = File.basename(file_path, fileext)

in_file_dirname = File.dirname(in_file_path)
in_file_basename = File.basename(in_file_path, ".in")
out_file_path = File.join(dirname, in_file_basename + ".out")
expected_out_path = File.join(in_file_dirname, in_file_basename + ".out")

command = {
".c" => "./a.out",
".cpp" => "./a.out",
".java" => "java #{basename}",
".pl" => "perl #{file_path}",
".py" => "python #{file_path}",
".rb" => "ruby #{file_path}",
".sh" => "./#{file_path}",
}[fileext]

if !command
puts "Your language is not supported, or unknown file extension"
return false
end

system("cd #{dirname} && #{command} < #{in_file_path} > #{out_file_path}")

if !File.exists?(out_file_path)
return false
end

system("diff -b #{expected_out_path} #{out_file_path} > /dev/null")
end

def move_submission(old_file, graded_dir)
user = File.basename(old_file)
index = (1..1.0/0).find{|e| !File.exist?("#{graded_dir}/#{user}.#{e}")}
File.rename(old_file,"#{graded_dir}/#{user}.#{index}")
end

def grade(user, args)
if !$admin_users.include?(user)
#return false
return false
end

problem = args.shift
submitter = args.shift
problems = args.any? ? [args.shift] : problem_list
submitter = args.any? ? args.shift : nil

problems.each do |problem|
in_files_path = File.join(problem_dir(problem), "tests", "*.in")
in_files = Dir[in_files_path]

submissions_paths = File.join(submission_dir(problem), "*")
submissions = Dir[submissions_paths]

puts 'Submitted files:'
system("ls #{submission_dir(problem, submitter)}")
submissions.each do |submission|
user = File.basename(submission)
next if !submitter.nil? and user != submitter

puts "\nGrading #{user} - #{problem}"

files_paths = File.join(submission_dir(problem, user), "*")
files = Dir[files_paths]
if files.size != 1
puts "#{files.size} files submitted, expected 1"
next
end
file = files.first

compile(file)
success = true
in_files.each do |in_file_path|
success &= run(file, in_file_path)
puts "\t#{File.basename in_file_path}: #{success ? "Passed" : "Failed"}"
end
puts "Result: #{success ? "Passed" : "Failed"}"
move_submission(submission, "#{problem_dir(problem)}/graded/")
end
end
true
end

def contests(user, args)
Expand Down Expand Up @@ -162,11 +261,9 @@ def contests(user, args)
def problems(user, args)
in_name = args[0]
prob_names = {}
problem_paths = File.join($problem_loc, $default_contest, "*")

Dir[problem_paths].each do |path|
name = Pathname.new(path).basename.to_s.split('.').first
prob_names[name] = path
problem_list.each do |problem_name|
prob_names[problem_name] = File.join(problem_dir(problem_name), "problem.txt")
end

if prob_names.keys.include? in_name
Expand Down