<commit_before>class AssignmentType < ActiveRecord::Base
  attr_accessible :due_date_present, :levels, :max_value, :name,
    :percentage_course, :point_setting, :points_predictor_display,
    :predictor_description, :resubmission, :universal_point_value, :course,
    :course_id, :order_placement, :student_weightable, :mass_grade,
    :score_levels_attributes, :score_level, :mass_grade_type, :course,
    :student_logged_revert_button_text, :student_logged_button_text,
    :notify_released

  belongs_to :course
  belongs_to :grade_scheme
  has_many :assignments
  has_many :submissions, :through => :assignments
  has_many :assignment_weights
  has_many :grades
  has_many :score_levels, -> { order "value" }
  accepts_nested_attributes_for :score_levels, allow_destroy: true

  validates_presence_of :name, :points_predictor_display, :point_setting
  before_save :ensure_score_levels

  scope :student_weightable, -> { where(:student_weightable => true) }
  scope :ordered, -> { order 'order_placement ASC' }
  scope :weighted_for_student, ->(student) { joins("LEFT OUTER JOIN assignment_weights ON assignment_types.id = assignment_weights.assignment_type_id AND assignment_weights.student_id = '#{sanitize student.id}'") }

  def self.weights_for_student(student)
    group('assignment_types.id').weighted_for_student(student).pluck('assignment_types.id, COALESCE(MAX(assignment_weights.weight), 0)')
  end

  def weight_for_student(student)
    return 1 unless student_weightable?
    assignment_weights.where(student: student).weight
  end

  #These determine how assignment types appears in the predictor
  def slider?
    points_predictor_display == "Slider"
  end

  def fixed?
    points_predictor_display == "Fixed"
  end

  def select?
    points_predictor_display == "Select List"
  end

  def per_assignment?
    points_predictor_display == "Set per Assignment"
  end

  #Checks if the assignment type has associated score levels
  def has_levels?
    score_levels.present?
  end

  #Powers the To Do list, checks if there are assignments within the next week (soon is a scope in the Assignment model)
  def has_soon_assignments?
    assignments.any?(&:soon?)
  end

  #Determines how the assignment type is handled in Quick Grade
  def grade_checkboxes?
    mass_grade_type == "Checkbox"
  end

  def grade_select?
    mass_grade_type == "Select List"
  end

  def grade_radio?
    mass_grade_type == "Radio Buttons"
  end

  def grade_text?
    mass_grade_type == "Text"
  end

  def grade_per_assignment?
    mass_grade_type == "Set per Assignment"
  end

  private

  def ensure_score_levels
    if mass_grade_type == "Select List" || mass_grade_type == "Radio Buttons"
      if score_levels.count <= 1
        errors.add(:assignment_type, "To use the selected method of quick grading you must create at least 2 score levels")
      end
    end
  end

end<commit_msg>Update per Steve's feedback<commit_after>class AssignmentType < ActiveRecord::Base
  attr_accessible :due_date_present, :levels, :max_value, :name,
    :percentage_course, :point_setting, :points_predictor_display,
    :predictor_description, :resubmission, :universal_point_value, :course,
    :course_id, :order_placement, :student_weightable, :mass_grade,
    :score_levels_attributes, :score_level, :mass_grade_type, :course,
    :student_logged_revert_button_text, :student_logged_button_text,
    :notify_released

  belongs_to :course
  belongs_to :grade_scheme
  has_many :assignments
  has_many :submissions, :through => :assignments
  has_many :assignment_weights
  has_many :grades
  has_many :score_levels, -> { order "value" }
  accepts_nested_attributes_for :score_levels, allow_destroy: true

  validates_presence_of :name, :points_predictor_display, :point_setting
  before_save :ensure_score_levels, :if => :multi_select?

  scope :student_weightable, -> { where(:student_weightable => true) }
  scope :ordered, -> { order 'order_placement ASC' }
  scope :weighted_for_student, ->(student) { joins("LEFT OUTER JOIN assignment_weights ON assignment_types.id = assignment_weights.assignment_type_id AND assignment_weights.student_id = '#{sanitize student.id}'") }

  def self.weights_for_student(student)
    group('assignment_types.id').weighted_for_student(student).pluck('assignment_types.id, COALESCE(MAX(assignment_weights.weight), 0)')
  end

  def weight_for_student(student)
    return 1 unless student_weightable?
    assignment_weights.where(student: student).weight
  end

  #These determine how assignment types appears in the predictor
  def slider?
    points_predictor_display == "Slider"
  end

  def fixed?
    points_predictor_display == "Fixed"
  end

  def select?
    points_predictor_display == "Select List"
  end

  def per_assignment?
    points_predictor_display == "Set per Assignment"
  end

  #Checks if the assignment type has associated score levels
  def has_levels?
    score_levels.present?
  end

  #Powers the To Do list, checks if there are assignments within the next week (soon is a scope in the Assignment model)
  def has_soon_assignments?
    assignments.any?(&:soon?)
  end

  #Determines how the assignment type is handled in Quick Grade
  def grade_checkboxes?
    mass_grade_type == "Checkbox"
  end

  def grade_select?
    mass_grade_type == "Select List"
  end

  def grade_radio?
    mass_grade_type == "Radio Buttons"
  end

  def grade_text?
    mass_grade_type == "Text"
  end


  def multi_select?
    grade_select? || grade_radio?
  end

  def grade_per_assignment?
    mass_grade_type == "Set per Assignment"
  end

  private

  def ensure_score_levels
    if score_levels.count <= 1
      errors.add(:assignment_type, "To use the selected method of quick grading you must create at least 2 score levels")
    end
  end

end
{'fraction_non_alphanumeric': 0.08127269583261283, 'fraction_numerical': 0.0013833650354487291, 'mean_word_length': 4.738095238095238, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 16, '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': '7031970', 'n_tokens_mistral': 1876, 'n_tokens_neox': 1790, 'n_words': 473}