Browse Source

More work on tasks and UI.

master
Ben Kurtovic 8 years ago
parent
commit
d30deac32b
7 changed files with 91 additions and 46 deletions
  1. +7
    -0
      README.md
  2. +5
    -5
      lib/kgrader/cli.rb
  3. +2
    -2
      lib/kgrader/course.rb
  4. +2
    -2
      lib/kgrader/roster.rb
  5. +32
    -3
      lib/kgrader/submission.rb
  6. +39
    -32
      lib/kgrader/task.rb
  7. +4
    -2
      rakefile

+ 7
- 0
README.md View File

@@ -10,6 +10,13 @@ It is written in Ruby.
Installation
------------

kgrader was developed using Ruby 2.2, though it should work with any recent
version of Ruby.

Install dependencies with gem:

gem install ruby-progressbar

Download kgrader over git:

git clone https://github.com/earwig/kgrader.git kgrader


+ 5
- 5
lib/kgrader/cli.rb View File

@@ -24,21 +24,21 @@ module KGrader
course.roster(semester).load rosterfile
end

def grade(course, semester, assignment, options = {})
def grade(course, semester, assignment, students = nil, options = {})
course = Course.new(@fs, course)
semester ||= course.current_semester
course.task(semester, assignment).grade options
course.task(semester, assignment, students).grade options
end

def commit(course, semester, assignment, options = {})
def commit(course, semester, assignment, students = nil)
course = Course.new(@fs, course)
semester ||= course.current_semester
course.task(semester, assignment).commit options
course.task(semester, assignment, students).commit
end

def clean
# TODO: also purge uncommitted grades
clear_jail
# TODO: also purge uncommitted grades: set all graded to ungraded and delete all pending files
end

def clobber


+ 2
- 2
lib/kgrader/course.rb View File

@@ -23,8 +23,8 @@ module KGrader
@assignments[name] ||= Assignment.new @fs, self, name
end

def task(semester, assignment)
Task.new @fs, self, semester, assignment
def task(semester, assignment, students = nil)
Task.new @fs, self, semester, assignment, students
end

def rosters


+ 2
- 2
lib/kgrader/roster.rb View File

@@ -10,7 +10,7 @@ module KGrader
end

def load(filename)
@students = @fs.load(filename).map! { |item| item.first }
@students = @fs.load(filename).map! &:first
FileUtils.mkdir_p File.dirname(rosterfile)
File.write rosterfile, @students.join("\n")
rescue FilesystemError => err
@@ -18,7 +18,7 @@ module KGrader
end

def students
@students ||= @fs.load(rosterfile).map! { |item| item.first }
@students ||= @fs.load(rosterfile).map! &:first
rescue FilesystemError
raise RosterError, "unknown semester: #{semester}"
end


+ 32
- 3
lib/kgrader/submission.rb View File

@@ -29,6 +29,7 @@ module KGrader
def create
FileUtils.mkdir_p @root
self.status = :init
nil
end

def fetch(due)
@@ -43,20 +44,48 @@ module KGrader
rewind due
self.status = revision == oldrev ? :graded : :ungraded
end
nil
end

def grade
# TODO
# TODO:
# self.status = :ungraded
# [grade the stuff]
# [save report to gradefile]
# FileUtils.touch pendingfile
# self.status = :graded
# return grade summary string

sleep rand / 2
'100%'
end

def commit
# TODO:
# if status == :graded && File.exists? pendingfile
# [copy gradefile to repo and commit]
# FileUtils.rm pendingfile
# end

sleep rand / 2
nil
end

private
def repo
File.join @root, "repo"
end

def statusfile
File.join @root, "status.txt"
end

def repo
File.join @root, "repo"
def gradefile
File.join @root, "grade.txt"
end

def pendingfile
File.join @root, "pending"
end

def revision


+ 39
- 32
lib/kgrader/task.rb View File

@@ -1,64 +1,71 @@
require 'ruby-progressbar'

module KGrader
class Task

def initialize(filesystem, course, semester, assignment)
@fs = filesystem
@course = course
@semester = semester

@assignment = @course.assignment assignment
@students = @course.roster(@semester).students
def initialize(filesystem, course, semester, assignment, students = nil)
@fs = filesystem
@course = course
@semester = semester
@assignment = @course.assignment assignment
@submissions = get_submissions students
end

def grade(options = {})
submissions = get_submissions options[:students]
due = options.fetch(:due, Time.now)
fetch = options.fetch(:fetch, true)
regrade = options.fetch(:regrade, false)

count = submissions.count
puts "[grading #{count} student#{'s' if count != 1}]"

submissions.each do |sub|
unless sub.exists?
puts "[init #{sub.student}]"
sub.create
end
subtask 'setup' do |sub|
sub.create unless sub.exists?
end

if fetch
submissions.each do |sub|
puts "[fetch #{sub.student}]"
subtask 'fetch' do |sub|
sub.fetch due
end
end

submissions.each do |sub|
sub.status = :ungraded if regrade
if sub.status == :ungraded
puts "[grade #{sub.student}]"
subtask 'grade' do |sub|
if sub.status == :init || sub.status == :fetching
next 'skip (need to fetch first)'
elsif sub.status == :graded && !regrade
next
else
sub.grade
end
end
end

def commit(options = {})
submissions = get_submissions options[:students]

# TODO
puts "[committing]"
puts "course => #{@course.name}"
puts "semester => #{@semester}"
puts "assignment => #{@assignment.name}"
puts "students => #{submissions.map { |sub| sub.student }.join ', '}"
def commit
subtask 'commit', &:commit
end

private
def get_submissions(students)
students.nil? ? (students = @students) : (students &= @students)
roster = @course.roster(@semester).students
students.nil? ? (students = roster) : (students &= roster)
students.map do |student|
Submission.new @fs, @course, @semester, @assignment, student
end
end

def student_len
@student_len ||= @submissions.map { |sub| sub.student.length }.max
end

def subtask(name)
progress = ProgressBar.create title: name, total: @submissions.size,
throttle_rate: 0, format: '%t [%b>%i] %j%% %e '

@submissions.each.with_index do |sub, i|
job = "#{name} [#{sub.student.ljust student_len}]"
progress.title = "#{job}:"
result = yield sub
progress.title = name if i == @submissions.size - 1
progress.log "#{job}#{': ' if result}#{result}" if result
progress.increment
end
end
end
end

+ 4
- 2
rakefile View File

@@ -45,13 +45,15 @@ task :grade do
course, assignment, options = parse_args 2..2,
{ :semester => :string, :students => :array, :due => :time,
:fetch => :bool, :regrade => :bool }
run { |cli| cli.grade course, options[:semester], assignment, options }
semester, students = options[:semester], options[:students]
run { |cli| cli.grade course, semester, assignment, students, options }
end

task :commit do
course, assignment, options = parse_args 2..2,
{ :semester => :string, :students => :array }
run { |cli| cli.commit course, options[:semester], assignment, options }
semester, students = options[:semester], options[:students]
run { |cli| cli.commit course, semester, assignment, students }
end

task :clean do


Loading…
Cancel
Save