A code autograder for student homework submissions
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

76 lignes
1.9 KiB

  1. require 'ruby-progressbar'
  2. module KGrader
  3. class Task
  4. def initialize(filesystem, course, semester, assignment, students = nil)
  5. @fs = filesystem
  6. @course = course
  7. @semester = semester
  8. @assignment = @course.assignment assignment
  9. @submissions = get_submissions students
  10. end
  11. def grade(options = {})
  12. due = options.fetch(:due, Time.now)
  13. fetch = options.fetch(:fetch, true)
  14. regrade = options.fetch(:regrade, false)
  15. if options.include?(:due) && !fetch
  16. raise TaskError, "can't set a new due date without fetching"
  17. end
  18. subtask 'setup' do |sub|
  19. sub.create unless sub.exists?
  20. end
  21. if fetch
  22. subtask 'fetch' do |sub|
  23. sub.fetch due
  24. end
  25. end
  26. subtask 'grade' do |sub|
  27. if sub.status == :init || sub.status == :fetching
  28. next 'skip (need to fetch first)'
  29. elsif sub.status == :graded && !regrade
  30. next
  31. else
  32. sub.grade
  33. end
  34. end
  35. end
  36. def commit
  37. subtask 'commit', &:commit
  38. end
  39. private
  40. def get_submissions(students)
  41. roster = @course.roster(@semester).students
  42. students.nil? ? (students = roster) : (students &= roster)
  43. students.map do |student|
  44. Submission.new @fs, @course, @semester, @assignment, student
  45. end
  46. end
  47. def student_len
  48. @student_len ||= @submissions.map { |sub| sub.student.length }.max
  49. end
  50. def subtask(name)
  51. progress = ProgressBar.create title: name, total: @submissions.size,
  52. throttle_rate: 0, format: '%t [%b>%i] %j%% %e '
  53. @submissions.each.with_index do |sub, i|
  54. job = "#{name} [#{sub.student.ljust student_len}]"
  55. progress.title = "#{job}:"
  56. result = yield sub
  57. progress.title = name if i == @submissions.size - 1
  58. progress.log "#{job}#{': ' if result}#{result}" if result
  59. progress.increment
  60. end
  61. end
  62. end
  63. end