<commit_before>class Assignment < ActiveRecord::Base
  require 'ftools'
  include DynamicReviewMapping

  belongs_to :course, :class_name => 'Course', :foreign_key => 'course_id'
  belongs_to :wiki_type
  # wiki_type needs to be removed. When an assignment is created, it needs to
  # be created as an instance of a subclass of the Assignment (model) class;
  # then Rails will "automatically" set the type field to the value that
  # designates an assignment of the appropriate type.
  has_many :participants, :class_name => 'AssignmentParticipant', :foreign_key => 'parent_id'
  has_many :users, :through => :participants
  has_many :due_dates
  has_many :teams, :class_name => 'AssignmentTeam', :foreign_key => 'parent_id'
  has_many :invitations, :class_name => 'Invitation', :foreign_key => 'assignment_id'
  has_many :assignment_questionnaires, :class_name => 'AssignmentQuestionnaires', :foreign_key => 'assignment_id'
  has_many :questionnaires, :through => :assignment_questionnaires
  belongs_to  :instructor, :class_name => 'User', :foreign_key => 'instructor_id'    
  has_many :sign_up_topics, :foreign_key => 'assignment_id', :dependent => :destroy  

  validates_presence_of :name
  validates_uniqueness_of :scope => [:directory_path, :instructor_id]

  COMPLETE = "Complete"

  #  Review Strategy information.
  RS_INSTRUCTOR_SELECTED = 'Instructor-Selected'
  RS_STUDENT_SELECTED    = 'Student-Selected'
  RS_AUTO_SELECTED       = 'Auto-Selected'
  REVIEW_STRATEGIES = [RS_INSTRUCTOR_SELECTED, RS_STUDENT_SELECTED, RS_AUTO_SELECTED]

  DEFAULT_MAX_REVIEWERS = 3

  # Here we set up the @contributors attribute to use participants/teams polymorphically
  def after_initialize
    self.review_strategy_id = nil 
    self.mapping_strategy_id = nil
  end
  
  def assign_reviewer_dynamically(reviewer, topic)
    # The following method raises an exception if not successful which 
    # has to be captured by the caller (in review_mapping_controller)
    contributor = contributor_to_review(reviewer, topic)
    
    contributor.assign_reviewer(reviewer)
  end
  
  # Returns a contributor to review if available, otherwise will raise an error
  def contributor_to_review(reviewer, topic)
    contributor_set = Array.new(@contributors)
    work = (topic.nil?) ? 'assignment' : 'topic'

    # 1) Filter by topic; 2) remove reviewer as contributor
    # 3) remove contributors that have not submitted work yet
    contributor_set.reject! do |contributor| 
      contributor.topic != topic or # both will be nil for assignments with no signup sheet
        contributor.includes?(reviewer) or
        !contributor.has_submissions?
    end
    raise "There are no more submissions to review on this #{work}." if contributor_set.empty?

    # Reviewer can review only once each contributor
    contributor_set.reject! { |contributor| contributor.reviewed_by?(reviewer) }
    raise "You have already reviewed all sumbmissions for this #{work}." if contributor_set.empty?

    # Reduce to the contributors with the least number of received responses
    contributor_set.sort! { |a, b| a.responses.count <=> b.responses.count }
    min_reviews = contributor_set.first.responses.count
    contributor_set.reject! { |contributor| contributor.responses.count > min_reviews }
<commit_msg>Use contributors instead of @contributors. Otherwise there is a bug there.<commit_after>class Assignment < ActiveRecord::Base
  require 'ftools'
  include DynamicReviewMapping

  belongs_to :course, :class_name => 'Course', :foreign_key => 'course_id'
  belongs_to :wiki_type
  # wiki_type needs to be removed. When an assignment is created, it needs to
  # be created as an instance of a subclass of the Assignment (model) class;
  # then Rails will "automatically" set the type field to the value that
  # designates an assignment of the appropriate type.
  has_many :participants, :class_name => 'AssignmentParticipant', :foreign_key => 'parent_id'
  has_many :users, :through => :participants
  has_many :due_dates
  has_many :teams, :class_name => 'AssignmentTeam', :foreign_key => 'parent_id'
  has_many :invitations, :class_name => 'Invitation', :foreign_key => 'assignment_id'
  has_many :assignment_questionnaires, :class_name => 'AssignmentQuestionnaires', :foreign_key => 'assignment_id'
  has_many :questionnaires, :through => :assignment_questionnaires
  belongs_to  :instructor, :class_name => 'User', :foreign_key => 'instructor_id'    
  has_many :sign_up_topics, :foreign_key => 'assignment_id', :dependent => :destroy  

  validates_presence_of :name
  validates_uniqueness_of :scope => [:directory_path, :instructor_id]

  COMPLETE = "Complete"

  #  Review Strategy information.
  RS_INSTRUCTOR_SELECTED = 'Instructor-Selected'
  RS_STUDENT_SELECTED    = 'Student-Selected'
  RS_AUTO_SELECTED       = 'Auto-Selected'
  REVIEW_STRATEGIES = [RS_INSTRUCTOR_SELECTED, RS_STUDENT_SELECTED, RS_AUTO_SELECTED]

  DEFAULT_MAX_REVIEWERS = 3

  # Here we set up the @contributors attribute to use participants/teams polymorphically
  def after_initialize
    self.review_strategy_id = nil 
    self.mapping_strategy_id = nil
  end
  
  def assign_reviewer_dynamically(reviewer, topic)
    # The following method raises an exception if not successful which 
    # has to be captured by the caller (in review_mapping_controller)
    contributor = contributor_to_review(reviewer, topic)
    
    contributor.assign_reviewer(reviewer)
  end
  
  # Returns a contributor to review if available, otherwise will raise an error
  def contributor_to_review(reviewer, topic)
    contributor_set = Array.new(contributors)
    work = (topic.nil?) ? 'assignment' : 'topic'

    # 1) Filter by topic; 2) remove reviewer as contributor
    # 3) remove contributors that have not submitted work yet
    contributor_set.reject! do |contributor| 
      contributor.topic != topic or # both will be nil for assignments with no signup sheet
        contributor.includes?(reviewer) or
        !contributor.has_submissions?
    end
    raise "There are no more submissions to review on this #{work}." if contributor_set.empty?

    # Reviewer can review each contributor only once 
    contributor_set.reject! { |contributor| contributor.reviewed_by?(reviewer) }
    raise "You have already reviewed all submissions for this #{work}." if contributor_set.empty?

    # Reduce to the contributors with the least number of received responses
    contributor_set.sort! { |a, b| a.responses.count <=> b.responses.count }
    min_reviews = contributor_set.first.responses.count
    contributor_set.reject! { |contributor| contributor.responses.count > min_reviews }

{'fraction_non_alphanumeric': 0.08288125376732972, 'fraction_numerical': 0.0012055455093429777, 'mean_word_length': 4.596121416526138, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5490173', 'n_tokens_mistral': 2031, 'n_tokens_neox': 1969, 'n_words': 590}