#!/usr/bin/env ruby require "flex_station_data/services/load_plates" require "flex_station_data/presenters/plates_hash" module FlexStationData class LinearRegressionApp include Concerns::Service OPTION_RE = /\A--(\w+(?:-\w+)*)(?:=(.*))?\z/.freeze attr_reader :args, :options def initialize(*args) @options, @args = args.partition { |arg| arg =~ OPTION_RE } @options.map! do |option| option.scan(OPTION_RE).first end end def option(option_name) name, value = options.reverse.detect { |name, _| name == option_name.to_s } return if name.blank? value.nil? || value end def threshold Float(option(:threshold)) rescue nil end def min_r_squared Float(option("min-r-squared")) rescue 0.75 end def files @files ||= args.map { |arg| Pathname(arg) } end def plates @plates ||= files.map do |file| [ file, LoadPlates.call(file) ] end end def plate_hashes plates.flat_map do |file, file_plates| Presenters::PlatesHash.present( file, file_plates, threshold: threshold, min_r_squared: min_r_squared ) end end def clean_values(values) values.each_with_object([]) do |value, memo| memo << ((value != memo.compact.last) ? value : nil) end end def hash @hash ||= begin result = plate_hashes.each_with_object({}) do |hash, memo| hash.each do |header, value| memo[header] ||= [] memo[header] << value end end result["file"] = clean_values(result["file"]) result["plate"] = clean_values(result["plate"]) result end end def csv [ hash.keys, *hash.values.transpose ] end def call CSV do |out| csv.each do |row| out << row end end end end end FlexStationData::LinearRegressionApp.call(*ARGV)