a9621fee449af062bf1cbd8a484cdaf4eea02e75
1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Simple numerical statistical analysis and presentation
18 # A counter counts occurrences of things
19 # Use this instead of a HashMap[E, Int]
20 class Counter[E
: Object]
23 # Total number of counted occurrences
26 private var map
= new HashMap[E
, Int]
28 # The number of counted occurrences of `e'
29 redef fun [](e
: E
): Int
32 if map
.has_key
(e
) then return map
[e
]
36 redef fun []=(e
: E
, value
: Int)
43 redef fun keys
do return map
.keys
45 redef fun values
do return map
.values
47 # Count one more occurrence of `e'
50 self.map
[e
] = self[e
] + 1
54 # Return an array of elements sorted by occurrences
57 var res
= map
.keys
.to_a
58 var sorter
= new CounterSorter[E
](self)
60 #res.sort !cmp a, b = map[a] <=> map[b]
64 # Display statistical information
68 print
" population: {list.length}"
69 if list
.is_empty
then return
70 print
" minimum value: {self[list.first]}"
71 print
" maximum value: {self[list.last]}"
72 print
" total value: {self.total}"
73 print
" average value: {div(self.total,list.length)}"
74 print
" distribution:"
77 var limit
= self[list
.first
]
79 if self[t
] > limit
then
80 print
" <={limit}: sub-population={count} ({div(count*100,list.length)}%); cumulated value={sum} ({div(sum*100,self.total)}%)"
83 while self[t
] > limit
do
85 if limit
== 0 then limit
= 1
91 print
" <={limit}: sub-population={count} ({div(count*100,list.length)}%); cumulated value={sum} ({div(sum*100,self.total)}%)"
95 private class CounterSorter[E
: Object]
96 super AbstractSorter[E
]
97 var counter
: Counter[E
]
98 redef fun compare
(a
,b
) do return self.counter
.map
[a
] <=> self.counter
.map
[b
]
101 # Helper function to display n/d and handle division by 0
102 fun div
(n
: Int, d
: Int): String
104 if d
== 0 then return "na"
105 return ((100*n
/d
).to_f
/100.0).to_precision
(2)