123 lines
2.7 KiB
Go
123 lines
2.7 KiB
Go
package exchangeUtility
|
|
|
|
import (
|
|
"sort"
|
|
)
|
|
|
|
const (
|
|
Mean string = "Mean"
|
|
Median string = "Median"
|
|
Mode string = "Mode"
|
|
Min string = "Min"
|
|
Max string = "Max"
|
|
)
|
|
|
|
type AggregateDailyToMonthly struct {
|
|
AggregatedNumbers []float64
|
|
}
|
|
|
|
func (mm *AggregateDailyToMonthly) CalcValue(avgMethod string) float64 {
|
|
switch avgMethod {
|
|
case Mean:
|
|
return mm.CalcMean()
|
|
case Median:
|
|
return mm.CalcMedian()
|
|
case Mode:
|
|
return mm.CalcMode()
|
|
case Max:
|
|
return mm.GetMaxValue()
|
|
case Min:
|
|
return mm.GetMinValue()
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// return the minimum value
|
|
func (mm *AggregateDailyToMonthly) GetMinValue() float64 {
|
|
sort.Float64s(mm.AggregatedNumbers) // sort the numbers
|
|
|
|
return mm.AggregatedNumbers[0]
|
|
}
|
|
|
|
// return the maximum value
|
|
func (mm *AggregateDailyToMonthly) GetMaxValue() float64 {
|
|
sort.Float64s(mm.AggregatedNumbers) // sort the numbers
|
|
|
|
return mm.AggregatedNumbers[len(mm.AggregatedNumbers)-1]
|
|
}
|
|
|
|
// calculate and return mode
|
|
func (mm *AggregateDailyToMonthly) CalcMode() float64 {
|
|
var modes []float64
|
|
frequencies := make(map[float64]int, len(mm.AggregatedNumbers))
|
|
highestFrequency := 0
|
|
for _, x := range mm.AggregatedNumbers {
|
|
frequencies[x]++
|
|
if frequencies[x] > highestFrequency {
|
|
highestFrequency = frequencies[x]
|
|
}
|
|
}
|
|
for x, frequency := range frequencies {
|
|
if frequency == highestFrequency {
|
|
modes = append(modes, x)
|
|
}
|
|
}
|
|
if highestFrequency == 1 || len(modes) == len(mm.AggregatedNumbers) {
|
|
modes = modes[:0] // Or: modes = []float64{}
|
|
}
|
|
sort.Float64s(modes)
|
|
mm.AggregatedNumbers = modes
|
|
|
|
return mm.CalcMean()
|
|
|
|
}
|
|
|
|
// calculate the range values
|
|
// last value - first value
|
|
func (mm *AggregateDailyToMonthly) CalcRangeValues() float64 {
|
|
sort.Float64s(mm.AggregatedNumbers) // sort the numbers
|
|
|
|
return mm.GetMaxValue() - mm.GetMinValue()
|
|
}
|
|
|
|
// calculate the "mean" value
|
|
// sum of all the values
|
|
// divided by its quantity
|
|
func (mm *AggregateDailyToMonthly) CalcMean() float64 {
|
|
total := 0.0
|
|
|
|
for _, v := range mm.AggregatedNumbers {
|
|
total += v
|
|
}
|
|
|
|
return total / float64(len(mm.AggregatedNumbers))
|
|
}
|
|
|
|
// calculate the "median" value
|
|
// if the total of numbers is odd
|
|
// takes the middle value
|
|
//
|
|
// if the total of numbers is even
|
|
// calculate the "mean" of the middle two values
|
|
func (mm *AggregateDailyToMonthly) CalcMedian() float64 {
|
|
sort.Float64s(mm.AggregatedNumbers) // sort the numbers
|
|
|
|
mNumber := len(mm.AggregatedNumbers) / 2
|
|
|
|
if mm.IsOdd() {
|
|
return mm.AggregatedNumbers[mNumber]
|
|
}
|
|
|
|
return (mm.AggregatedNumbers[mNumber-1] + mm.AggregatedNumbers[mNumber]) / 2
|
|
}
|
|
|
|
// check if the total of numbers is
|
|
// odd or even
|
|
func (mm *AggregateDailyToMonthly) IsOdd() bool {
|
|
if len(mm.AggregatedNumbers)%2 == 0 {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|