+ # Type of values used to measure elements.
+ type VAL: Object
+
+ # Type of data representation used to associate elements and values.
+ type RES: Map[ELM, VAL]
+
+ # The name of this metric (generally an acronym about the metric).
+ fun name: String is abstract
+
+ # A long and understandable description about what is measured by this metric.
+ fun desc: String is abstract
+
+ # Clear all results for this metric
+ fun clear is abstract
+
+ # Values for each element
+ fun values: RES is abstract
+
+ # Collect metric values on elements
+ fun collect(elements: Collection[ELM]) is abstract
+
+ # The value calculated for the element
+ fun [](element: ELM): VAL do return values[element]
+
+ # Does the element have a value for this metric?
+ fun has_element(element: ELM): Bool do return values.has_key(element)
+
+ # The values average
+ fun avg: Float is abstract
+
+ # Pretty print the metric results in console
+ fun to_console(indent: Int, colors: Bool) do
+ if values.is_empty then
+ if colors then
+ print "{"\t" * indent}{name}: {desc} -- nothing".green
+ else
+ print "{"\t" * indent}{name}: {desc} -- nothing"
+ end
+ return
+ end
+
+ var max = self.max
+ var min = self.min
+ if colors then
+ print "{"\t" * indent}{name}: {desc}".green
+ print "{"\t" * indent} avg: {avg}".light_gray
+ print "{"\t" * indent} max: {max} ({self[max]})".light_gray
+ print "{"\t" * indent} min: {min} ({self[min]})".light_gray
+ print "{"\t" * indent} std: {std_dev}".light_gray
+ else
+ print "{"\t" * indent}{name}: {desc}"
+ print "{"\t" * indent} avg: {avg}"
+ print "{"\t" * indent} max: {max} ({self[max]})"
+ print "{"\t" * indent} min: {min} ({self[min]})"
+ print "{"\t" * indent} std: {std_dev}"
+ end