Merge: doc: fixed some typos and other misc. corrections
[nit.git] / src / metrics / metrics_base.nit
index 056aba4..959041b 100644 (file)
@@ -18,7 +18,7 @@
 # Helpers for various statistics tools.
 module metrics_base
 
-import model_utils
+import modelbuilder
 import csv
 import counter
 import console
@@ -50,18 +50,20 @@ redef class ToolContext
        var opt_tables = new OptionBool("Compute tables metrics", "--tables")
        # --rta
        var opt_rta = new OptionBool("Compute RTA metrics", "--rta")
+       # --readme
+       var opt_readme = new OptionBool("Compute ReadMe metrics", "--readme")
        # --generate-csv
-       var opt_csv = new OptionBool("Export metrics in CSV format", "--csv")
+       var opt_csv = new OptionBool("Also export metrics in CSV format", "--csv")
        # --generate_hyperdoc
        var opt_generate_hyperdoc = new OptionBool("Generate Hyperdoc", "--generate_hyperdoc")
        # --poset
        var opt_poset = new OptionBool("Complete metrics on posets", "--poset")
-
        # --no-colors
        var opt_nocolors = new OptionBool("Disable colors in console outputs", "--no-colors")
-
-
+       # --dir
        var opt_dir = new OptionString("Directory where some statistics files are generated", "-d", "--dir")
+
+       # Output directory for metrics files.
        var output_dir: String = "."
 
        redef init
@@ -79,6 +81,7 @@ redef class ToolContext
                self.option_context.add_option(opt_static_types)
                self.option_context.add_option(opt_tables)
                self.option_context.add_option(opt_rta)
+               self.option_context.add_option(opt_readme)
                self.option_context.add_option(opt_csv)
                self.option_context.add_option(opt_generate_hyperdoc)
                self.option_context.add_option(opt_poset)
@@ -86,7 +89,7 @@ redef class ToolContext
                self.option_context.add_option(opt_nocolors)
        end
 
-       redef fun process_options
+       redef fun process_options(args)
        do
                super
                var val = self.opt_dir.value
@@ -97,27 +100,41 @@ redef class ToolContext
                end
        end
 
-       # colorize heading 1 for console output
+       # Format and colorize a string heading of level 1 for console output.
+       #
+       # Default style is yellow and bold.
        fun format_h1(str: String): String do
                if opt_nocolors.value then return str
                return str.yellow.bold
        end
 
+       # Format and colorize a string heading of level 2 for console output.
+       #
+       # Default style is white and bold.
        fun format_h2(str: String): String do
                if opt_nocolors.value then return str
                return str.bold
        end
 
+       # Format and colorize a string heading of level 3 for console output.
+       #
+       # Default style is white and nobold.
        fun format_h3(str: String): String do
                if opt_nocolors.value then return str
                return str
        end
 
+       # Format and colorize a string heading of level 4 for console output.
+       #
+       # Default style is green.
        fun format_h4(str: String): String do
                if opt_nocolors.value then return str
                return str.green
        end
 
+       # Format and colorize a string heading of level 5 for console output.
+       #
+       # Default style is light gray.
        fun format_p(str: String): String do
                if opt_nocolors.value then return str
                return str.light_gray
@@ -125,29 +142,24 @@ redef class ToolContext
 
 end
 
-redef class MClass
-       # is the class imported from standard lib?
-       fun is_standard: Bool do
-               return self.intro_mmodule.mgroup.mproject.name == "standard"
-       end
-end
-
-redef class MModule
-       # is the module imported from standard lib?
-       fun is_standard: Bool do
-               return self.mgroup.mproject.name == "standard"
-       end
-end
-
 # A Metric is used to collect data about things
 #
 # The concept is reified here for a better organization and documentation
 interface Metric
+
+       # Type of elements measured by this metric.
        type ELM: Object
+
+       # 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
@@ -157,7 +169,7 @@ interface Metric
        fun values: RES is abstract
 
        # Collect metric values on elements
-       fun collect(elements: Set[ELM]) is abstract
+       fun collect(elements: Collection[ELM]) is abstract
 
        # The value calculated for the element
        fun [](element: ELM): VAL do return values[element]
@@ -170,6 +182,15 @@ interface Metric
 
        # 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
@@ -187,6 +208,9 @@ interface Metric
                end
        end
 
+       # The sum of all the values.
+       fun sum: VAL is abstract
+
        # The values standard derivation
        fun std_dev: Float is abstract
 
@@ -201,6 +225,11 @@ interface Metric
 
        # The set of element above the threshold
        fun above_threshold: Set[ELM] is abstract
+
+       # Sort the metric keys by values
+       fun sort: Array[ELM] do
+               return values.keys_sorted_by_values(default_reverse_comparator)
+       end
 end
 
 # A Metric that collects integer data
@@ -209,15 +238,17 @@ end
 class IntMetric
        super Metric
 
-       redef type VAL: Int
+       redef type VAL: Int is fixed
        redef type RES: Counter[ELM]
 
+       # `IntMetric` uses a Counter to store values in intern.
        protected var values_cache = new Counter[ELM]
+
        redef fun values do return values_cache
 
        redef fun clear do values_cache.clear
 
-       fun sum: Int do return values_cache.sum
+       redef fun sum do return values_cache.sum
 
        redef fun max do
                assert not values_cache.is_empty
@@ -230,9 +261,9 @@ class IntMetric
        end
 
        # Values average
-       redef fun avg: Float do return values_cache.avg
+       redef fun avg do return values_cache.avg
 
-       redef fun std_dev: Float do return values_cache.std_dev
+       redef fun std_dev do return values_cache.std_dev
 
        redef fun above_threshold do
                var above = new HashSet[ELM]
@@ -242,6 +273,15 @@ class IntMetric
                end
                return above
        end
+
+       redef fun to_console(indent, colors) do
+               super
+               if colors then
+                       print "{"\t" * indent}  sum: {sum}".light_gray
+               else
+                       print "{"\t" * indent}  sum: {sum}"
+               end
+       end
 end
 
 # A Metric that collects float datas
@@ -252,14 +292,20 @@ class FloatMetric
 
        redef type VAL: Float
 
+       # `FloatMetric` uses a Map to store values in intern.
        protected var values_cache = new HashMap[ELM, VAL]
+
        redef fun values do return values_cache
 
        redef fun clear do values_cache.clear
 
-       fun sum: Float do
+
+       redef fun sum do
                var sum = 0.0
-               for v in values.values do sum += v
+               for v in values.values do
+                       if v.is_nan then continue
+                       sum += v
+               end
                return sum
        end
 
@@ -294,9 +340,10 @@ class FloatMetric
                return sum / values.length.to_f
        end
 
-       redef fun std_dev: Float do
+       redef fun std_dev do
                var sum = 0.0
                for value in values.values do
+                       if value.is_nan then continue
                        sum += (value - avg).pow(2.to_f)
                end
                return (sum / values.length.to_f).sqrt
@@ -310,12 +357,23 @@ class FloatMetric
                end
                return above
        end
+
+       redef fun to_console(indent, colors) do
+               super
+               if colors then
+                       print "{"\t" * indent}  sum: {sum}".light_gray
+               else
+                       print "{"\t" * indent}  sum: {sum}"
+               end
+       end
 end
 
 # A MetricSet is a metric holder
 #
 # It purpose is to be extended with a metric collect service
 class MetricSet
+
+       # Type of element measured by this `MetricSet`.
        type ELM: Object
 
        # Metrics to compute
@@ -338,8 +396,9 @@ class MetricSet
        end
 
        # Export the metric set in CSV format
-       fun to_csv: CSVDocument do
-               var csv = new CSVDocument
+       fun to_csv: CsvDocument do
+               var csv = new CsvDocument
+               csv.separator = ';'
 
                # set csv headers
                csv.header.add("entry")
@@ -361,7 +420,7 @@ class MetricSet
                                        line.add("n/a")
                                end
                        end
-                       csv.lines.add(line)
+                       csv.records.add(line)
                end
                return csv
        end