<commit_before>class Task < ActiveRecord::Base
  has_many :taggings, dependent: :destroy
  has_many :tags, through: :taggings
  has_many :time_entries, dependent: :destroy
  belongs_to :user

  validates_presence_of :user_id, :task_name

  scope :order_last_touched, -> do
    includes(:time_entries).order('time_entries.start_time DESC')
  end
  scope :active, -> { where(archived_at: nil) }
  scope :archived, -> { where.not(archived_at: nil) }
  scope :order_todo, -> { all.sort_by(&:time_remaining_today).reverse }

  def time_spent
    self.time_entries.sum(:duration)
  end

  def percent_time_used
    if self.estimate.nil? || self.estimate.zero?
      return 0
    end

    (self.time_spent.to_f / self.estimate) * 100
  end

  def explicit_name
    "#{self.task_name} - #{self.tags.pluck(:name).join(", ")}"
  end

  def archived?
    self.archived_at.present?
  end

  def days_left
    (self.due_date - Date.today).to_i if self.due_date
  end

  def overdue?
    !archived? && days_left.present? && days_left < 0
  end

  def time_remaining_today
    return 0 unless due_date && estimate

    per_day = estimate - done_before_today
    per_day /= days_left.to_f if due_date > Date.today

    left_today = per_day - done_today
    return 0 if left_today < 0

    left_today
  end

  private

  def done_before_today
    today = Date.today.to_time
    entries_before_today = time_entries.where('start_time < ?', today)
    entries_before_today.sum(:duration)
  end

  def done_today
    today = Date.today.to_time
    todays_entries = time_entries.where('start_time >= ?', today)
    todays_entries.sum(:duration)
  end
end<commit_msg>Refactored even further<commit_after>class Task < ActiveRecord::Base
  has_many :taggings, dependent: :destroy
  has_many :tags, through: :taggings
  has_many :time_entries, dependent: :destroy
  belongs_to :user

  validates_presence_of :user_id, :task_name

  scope :order_last_touched, -> do
    includes(:time_entries).order('time_entries.start_time DESC')
  end
  scope :active, -> { where(archived_at: nil) }
  scope :archived, -> { where.not(archived_at: nil) }
  scope :order_todo, -> { all.sort_by(&:time_remaining_today).reverse }

  def time_spent
    self.time_entries.sum(:duration)
  end

  def percent_time_used
    if self.estimate.nil? || self.estimate.zero?
      return 0
    end

    (self.time_spent.to_f / self.estimate) * 100
  end

  def explicit_name
    "#{self.task_name} - #{self.tags.pluck(:name).join(", ")}"
  end

  def archived?
    self.archived_at.present?
  end

  def days_left
    (self.due_date - Date.today).to_i if self.due_date
  end

  def overdue?
    !archived? && days_left.present? && days_left < 0
  end

  def time_remaining_today
    return 0 unless due_date && estimate

    left_today = due_today - done_today

    if left_today < 0
      0
    else
      left_today
    end
  end

  private

  def done_before_today
    today = Date.today.to_time
    entries_before_today = time_entries.where('start_time < ?', today)
    entries_before_today.sum(:duration)
  end

  def due_today
    work_left = estimate - done_before_today

    if due_date > Date.today
      work_left / days_left.to_f
    else
      work_left
    end
  end

  def done_today
    today = Date.today.to_time
    todays_entries = time_entries.where('start_time >= ?', today)
    todays_entries.sum(:duration)
  end
end
{'fraction_non_alphanumeric': 0.10198049068873781, 'fraction_numerical': 0.004729530002955957, 'mean_word_length': 3.3329065300896286, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, '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': '4779080', 'n_tokens_mistral': 1265, 'n_tokens_neox': 1192, 'n_words': 250}