<commit_before>module Monet
  class DiffStrategy
    include ChunkyPNG::Color

    attr_reader :score

    def initialize(base_image, diff_image)
      @base_image = base_image
      @diff_image = diff_image
      @score = []

      raise Errors::DifferentDimensions unless dimensions_match?
    end

    def calculate_for_pixel(pixel, x, y)
      @score << [x,y] unless pixel == @diff_image[x,y]
    end

    def save(filename)
      @output.save(filename)
    end

    private
    def dimensions_match?
      @base_image.width == @diff_image.width &&
      @base_image.height == @diff_image.height
    end
  end

  class Grayscale < DiffStrategy
    def initialize(base_image, diff_image)
      super
      @output = ChunkyPNG::Image.new(base_image.width, base_image.height, WHITE)
    end

    def calculate_for_pixel(pixel, x, y)
      return if pixel == @diff_image[x,y]

      score = Math.sqrt(
        (r(@diff_image[x,y]) - r(pixel)) ** 2 +
        (g(@diff_image[x,y]) - g(pixel)) ** 2 +
        (b(@diff_image[x,y]) - b(pixel)) ** 2
      ) / Math.sqrt(MAX ** 2 * 3)

      @output[x,y] = grayscale(MAX - (score * MAX).round)
      super
    end
  end

  class ColorBlend < DiffStrategy
    def initialize(base_image, diff_image)
      super
      @output = ChunkyPNG::Image.new(base_image.width, diff_image.width, BLACK)
    end

    def calculate_for_pixel(pixel, x, y)
      @output[x,y] = rgb(
        r(pixel) + r(@diff_image[x,y]) - 2 * [r(pixel), r(@diff_image[x,y])].min,
        g(pixel) + g(@diff_image[x,y]) - 2 * [g(pixel), g(@diff_image[x,y])].min,
        b(pixel) + b(@diff_image[x,y]) - 2 * [b(pixel), b(@diff_image[x,y])].min
      )
      super
    end
  end
end<commit_msg>refactor<commit_after>module Monet
  class DiffStrategy
    include ChunkyPNG::Color

    attr_reader :score

    def initialize(base_image, diff_image)
      @base_image = base_image
      @diff_image = diff_image
      @score = []

      raise Errors::DifferentDimensions unless dimensions_match?
    end

    def calculate_for_pixel(pixel, x, y)
      @score << [x,y] unless pixel == @diff_image[x,y]
    end

    def save(filename)
      @output.save(filename)
    end

    private
    def dimensions_match?
      @base_image.width == @diff_image.width &&
      @base_image.height == @diff_image.height
    end
  end

  class Grayscale < DiffStrategy
    def initialize(base_image, diff_image)
      super
      @output = ChunkyPNG::Image.new(base_image.width, base_image.height, WHITE)
    end

    def calculate_for_pixel(pixel, x, y)
      return if pixel == @diff_image[x,y]

      score = Math.sqrt(
        (r(@diff_image[x,y]) - r(pixel)) ** 2 +
        (g(@diff_image[x,y]) - g(pixel)) ** 2 +
        (b(@diff_image[x,y]) - b(pixel)) ** 2
      ) / Math.sqrt(MAX ** 2 * 3)

      @output[x,y] = grayscale(MAX - (score * MAX).round)
      super
    end
  end

  class ColorBlend < DiffStrategy
    def initialize(base_image, diff_image)
      super
      @output = ChunkyPNG::Image.new(base_image.width, diff_image.width, BLACK)
    end

    def calculate_for_pixel(pixel, x, y)
      rgb_colors = %w(r g b).map do |color|
        for_color(color, pixel) + for_color(color, @diff_image[x,y]) - 2 * [for_color(color, pixel), for_color(color, @diff_image[x,y])].min
      end

      @output[x,y] = rgb(*rgb_colors)
      super
    end

    private
    def for_color(color, *params)
      send color, *params
    end
  end
end
{'fraction_non_alphanumeric': 0.13267384346814082, 'fraction_numerical': 0.004073319755600814, 'mean_word_length': 2.732899022801303, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 3, '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': '6170302', 'n_tokens_mistral': 1262, 'n_tokens_neox': 1212, 'n_words': 252}