<commit_before>require 'csv_invalid_line_error'

class Assignment < ActiveRecord::Base
  include RepositoryHelper
  MARKING_SCHEME_TYPE = {
    flexible: 'flexible',
    rubric: 'rubric'
  }

  has_many :rubric_criteria,
           -> { order(:position) },
           class_name: 'RubricCriterion',
		   dependent: :destroy

  has_many :flexible_criteria,
           -> { order(:position) },
           class_name: 'FlexibleCriterion',
		   dependent: :destroy

  has_many :criterion_ta_associations,
		   dependent: :destroy

  has_many :assignment_files,
		   dependent: :destroy
  accepts_nested_attributes_for :assignment_files, allow_destroy: true
  validates_associated :assignment_files

  has_many :test_files, dependent: :destroy
  accepts_nested_attributes_for :test_files, allow_destroy: true

  has_one :assignment_stat, dependent: :destroy
  accepts_nested_attributes_for :assignment_stat, allow_destroy: true
  validates_associated :assignment_stat
  # Because of app/views/main/_grade_distribution_graph.html.erb:25
  validates_presence_of :assignment_stat

  has_many :annotation_categories,
           -> { order(:position) },
           class_name: 'AnnotationCategory',
		   dependent: :destroy

  has_many :groupings

  has_many :ta_memberships, through: :groupings
  has_many :student_memberships, through: :groupings
  has_many :tokens, through: :groupings

  has_many :submissions, through: :groupings
  has_many :groups, through: :groupings

  has_many :notes, as: :noteable, dependent: :destroy

  has_many :section_due_dates
  accepts_nested_attributes_for :section_due_dates


  validates_uniqueness_of :short_identifier, case_sensitive: true
  validates_numericality_of :group_min, only_integer: true, greater_than: 0
  validates_numericality_of :group_max, only_integer: true, greater_than: 0
  validates_numericality_of :tokens_per_day, only_integer: true, greater_than_or_equal_to: 0

  has_one :submission_rule, dependent: :destroy, inverse_of: :assignment
  accepts_nested_attributes_for :submission_rule, allow_destroy: true
  validates_associated :submission_rule
  validates_presence_of :submission_rule

  validates_presence_of :short_identifier
  validates_presence_of :description
  validates_presence_of :repository_folder
  validates_presence_of :due_date
  validates_presence_of :marking_scheme_type
  validates_presence_of :group_min
  validates_presence_of :group_max
  validates_presence_of :notes_count
  # "validates_presence_of" for boolean values.
  validates_inclusion_of :allow_web_submits, in: [true, false]
  validates_inclusion_of :vcs_submit, in: [true, false]
  validates_inclusion_of :display_grader_names_to_students, in: [true, false]
  validates_inclusion_of :is_hidden, in: [true, false]
  validates_inclusion_of :enable_test, in: [true, false]
  validates_inclusion_of :assign_graders_to_criteria, in: [true, false]

  validate :minimum_number_of_groups

  before_save :reset_collection_time

  # Call custom validator in order to validate the :due_date attribute
  # date: true maps to DateValidator (custom_name: true maps to CustomNameValidator)
  # Look in lib/validators/* for more info
  validates :due_date, date: true
  after_save :update_assigned_tokens

  # Set the default order of assignments: in ascending order of due_date
  default_scope { order('due_date ASC') }

  # Export a YAML formatted string created from the assignment rubric criteria.
  def export_rubric_criteria_yml
    criteria = self.rubric_criteria
    final = ActiveSupport::OrderedHash.new
    criteria.each do |criterion|
      inner = ActiveSupport::OrderedHash.new
      inner['weight'] =  criterion['weight']
      inner['level_0'] = {
        'name' =>  criterion['level_0_name'] ,
        'description' =>  criterion['level_0_description']
      }
      inner['level_1'] = {
        'name' =>  criterion['level_1_name'] ,
        'description' =>  criterion['level_1_description']
      }
      inner['level_2'] = {
        'name' =>  criterion['level_2_name'] ,
        'description' =>  criterion['level_2_description']
      }
      inner['level_3'] = {
        'name' =>  criterion['level_3_name'] ,
        'description' =>  criterion['level_3_description']
      }
      inner['level_4'] = {
        'name' =>  criterion['level_4_name'] ,
        'description' => criterion['level_4_description']
      }
      criteria_yml = { "#{criterion['rubric_criterion_name']}" => inner }
      final = final.merge(criteria_yml)
    end
    final.to_yaml
  end

  def minimum_number_of_groups
    if (group_max && group_min) && group_max < group_min
      errors.add(:group_max, 'must be greater than the minimum number of groups')
      false
    end
  end

  # Are we past all the due dates for this assignment?
  def past_all_due_dates?
    # If no section due dates /!\ do not check empty? it could be wrong
    unless self.section_due_dates_type
      return !due_date.nil? && Time.zone.now > due_date
    end<commit_msg>Changed a string interpolation on assignment.rb<commit_after>require 'csv_invalid_line_error'

class Assignment < ActiveRecord::Base
  include RepositoryHelper
  MARKING_SCHEME_TYPE = {
    flexible: 'flexible',
    rubric: 'rubric'
  }

  has_many :rubric_criteria,
           -> { order(:position) },
           class_name: 'RubricCriterion',
		   dependent: :destroy

  has_many :flexible_criteria,
           -> { order(:position) },
           class_name: 'FlexibleCriterion',
		   dependent: :destroy

  has_many :criterion_ta_associations,
		   dependent: :destroy

  has_many :assignment_files,
		   dependent: :destroy
  accepts_nested_attributes_for :assignment_files, allow_destroy: true
  validates_associated :assignment_files

  has_many :test_files, dependent: :destroy
  accepts_nested_attributes_for :test_files, allow_destroy: true

  has_one :assignment_stat, dependent: :destroy
  accepts_nested_attributes_for :assignment_stat, allow_destroy: true
  validates_associated :assignment_stat
  # Because of app/views/main/_grade_distribution_graph.html.erb:25
  validates_presence_of :assignment_stat

  has_many :annotation_categories,
           -> { order(:position) },
           class_name: 'AnnotationCategory',
		   dependent: :destroy

  has_many :groupings

  has_many :ta_memberships, through: :groupings
  has_many :student_memberships, through: :groupings
  has_many :tokens, through: :groupings

  has_many :submissions, through: :groupings
  has_many :groups, through: :groupings

  has_many :notes, as: :noteable, dependent: :destroy

  has_many :section_due_dates
  accepts_nested_attributes_for :section_due_dates


  validates_uniqueness_of :short_identifier, case_sensitive: true
  validates_numericality_of :group_min, only_integer: true, greater_than: 0
  validates_numericality_of :group_max, only_integer: true, greater_than: 0
  validates_numericality_of :tokens_per_day, only_integer: true, greater_than_or_equal_to: 0

  has_one :submission_rule, dependent: :destroy, inverse_of: :assignment
  accepts_nested_attributes_for :submission_rule, allow_destroy: true
  validates_associated :submission_rule
  validates_presence_of :submission_rule

  validates_presence_of :short_identifier
  validates_presence_of :description
  validates_presence_of :repository_folder
  validates_presence_of :due_date
  validates_presence_of :marking_scheme_type
  validates_presence_of :group_min
  validates_presence_of :group_max
  validates_presence_of :notes_count
  # "validates_presence_of" for boolean values.
  validates_inclusion_of :allow_web_submits, in: [true, false]
  validates_inclusion_of :vcs_submit, in: [true, false]
  validates_inclusion_of :display_grader_names_to_students, in: [true, false]
  validates_inclusion_of :is_hidden, in: [true, false]
  validates_inclusion_of :enable_test, in: [true, false]
  validates_inclusion_of :assign_graders_to_criteria, in: [true, false]

  validate :minimum_number_of_groups

  before_save :reset_collection_time

  # Call custom validator in order to validate the :due_date attribute
  # date: true maps to DateValidator (custom_name: true maps to CustomNameValidator)
  # Look in lib/validators/* for more info
  validates :due_date, date: true
  after_save :update_assigned_tokens

  # Set the default order of assignments: in ascending order of due_date
  default_scope { order('due_date ASC') }

  # Export a YAML formatted string created from the assignment rubric criteria.
  def export_rubric_criteria_yml
    criteria = self.rubric_criteria
    final = ActiveSupport::OrderedHash.new
    criteria.each do |criterion|
      inner = ActiveSupport::OrderedHash.new
      inner['weight'] =  criterion['weight']
      inner['level_0'] = {
        'name' =>  criterion['level_0_name'] ,
        'description' =>  criterion['level_0_description']
      }
      inner['level_1'] = {
        'name' =>  criterion['level_1_name'] ,
        'description' =>  criterion['level_1_description']
      }
      inner['level_2'] = {
        'name' =>  criterion['level_2_name'] ,
        'description' =>  criterion['level_2_description']
      }
      inner['level_3'] = {
        'name' =>  criterion['level_3_name'] ,
        'description' =>  criterion['level_3_description']
      }
      inner['level_4'] = {
        'name' =>  criterion['level_4_name'] ,
        'description' => criterion['level_4_description']
      }
      criteria_yml = { "#{criterion.name}" => inner }
      final = final.merge(criteria_yml)
    end
    final.to_yaml
  end

  def minimum_number_of_groups
    if (group_max && group_min) && group_max < group_min
      errors.add(:group_max, 'must be greater than the minimum number of groups')
      false
    end
  end

  # Are we past all the due dates for this assignment?
  def past_all_due_dates?
    # If no section due dates /!\ do not check empty? it could be wrong
    unless self.section_due_dates_type
      return !due_date.nil? && Time.zone.now > due_date
    end
{'fraction_non_alphanumeric': 0.08576019280980117, 'fraction_numerical': 0.004016870857601928, 'mean_word_length': 4.360064585575888, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 33, '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': '5414438', 'n_tokens_mistral': 3256, 'n_tokens_neox': 3146, 'n_words': 698}