50 lines
1.5 KiB
Ruby
50 lines
1.5 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
module Ml
|
||
|
class CandidatesCsvPresenter
|
||
|
CANDIDATE_ASSOCIATIONS = [:latest_metrics, :params, :experiment].freeze
|
||
|
# This file size limit is mainly to avoid the generation to hog resources from the server. The value is arbitrary
|
||
|
# can be update once we have better insight into usage.
|
||
|
TARGET_FILESIZE = 2.megabytes
|
||
|
|
||
|
def initialize(candidates)
|
||
|
@candidates = candidates
|
||
|
end
|
||
|
|
||
|
def present
|
||
|
CsvBuilder.new(@candidates, headers, CANDIDATE_ASSOCIATIONS).render(TARGET_FILESIZE)
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def headers
|
||
|
metric_names = columns_names(&:metrics)
|
||
|
param_names = columns_names(&:params)
|
||
|
|
||
|
candidate_to_metrics = @candidates.to_h do |candidate|
|
||
|
[candidate.id, candidate.latest_metrics.to_h { |m| [m.name, m.value] }]
|
||
|
end
|
||
|
|
||
|
candidate_to_params = @candidates.to_h do |candidate|
|
||
|
[candidate.id, candidate.params.to_h { |m| [m.name, m.value] }]
|
||
|
end
|
||
|
|
||
|
{
|
||
|
project_id: 'project_id',
|
||
|
experiment_iid: ->(c) { c.experiment.iid },
|
||
|
candidate_iid: 'internal_id',
|
||
|
name: 'name',
|
||
|
external_id: 'eid',
|
||
|
start_time: 'start_time',
|
||
|
end_time: 'end_time',
|
||
|
**param_names.index_with { |name| ->(c) { candidate_to_params.dig(c.id, name) } },
|
||
|
**metric_names.index_with { |name| ->(c) { candidate_to_metrics.dig(c.id, name) } }
|
||
|
}
|
||
|
end
|
||
|
|
||
|
def columns_names(&selector)
|
||
|
@candidates.flat_map(&selector).map(&:name).uniq
|
||
|
end
|
||
|
end
|
||
|
end
|