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.

82 lignes
2.0 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. prepare
  19. subtask 'setup' do |sub|
  20. sub.create unless sub.exists?
  21. end
  22. if fetch
  23. subtask 'fetch' do |sub|
  24. sub.fetch due
  25. end
  26. end
  27. subtask 'grade' do |sub|
  28. if sub.status == :init || sub.status == :fetching
  29. next 'skip (need to fetch first)'
  30. elsif sub.status == :graded && !regrade
  31. next
  32. else
  33. sub.grade
  34. end
  35. end
  36. end
  37. def commit
  38. prepare
  39. subtask 'commit', &:commit
  40. end
  41. private
  42. def get_submissions(students)
  43. roster = @course.roster(@semester).students
  44. students.nil? ? (students = roster) : (students &= roster)
  45. students.map do |student|
  46. Submission.new @fs, @course, @semester, @assignment, student
  47. end
  48. end
  49. def student_len
  50. @student_len ||= @submissions.map { |sub| sub.student.length }.max
  51. end
  52. def prepare
  53. @course.backend.prepare @semester, @assignment
  54. end
  55. def subtask(name)
  56. progress = ProgressBar.create title: name, total: @submissions.size,
  57. throttle_rate: 0, format: '%t [%b>%i] %j%% %e '
  58. @submissions.each.with_index do |sub, i|
  59. job = "#{name} [#{sub.student.ljust student_len}]"
  60. progress.title = "#{job}:"
  61. result = yield sub
  62. progress.title = name if i == @submissions.size - 1
  63. progress.log "#{job}#{': ' if result}#{result}" if result
  64. progress.increment
  65. end
  66. end
  67. end
  68. end