Created
August 15, 2012 14:25
-
-
Save michalbcz/3360573 to your computer and use it in GitHub Desktop.
groovy - super basic stats and usage of class extensions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ------------------- methods and extensions definitions ----------------------------- | |
List.metaClass.grepWithIndex = { yield -> | |
def greppedCollection = [] | |
delegate.eachWithIndex { value, index -> | |
if (yield(value, index)) { | |
greppedCollection << value | |
} | |
} | |
return greppedCollection | |
} | |
List.metaClass.mean = { | |
this.&mean(delegate) | |
} | |
def mean(numbers) { | |
numbers.sum() / numbers.size() | |
} | |
List.metaClass.median = { | |
this.&median(delegate) | |
} | |
def median(numbers) { | |
def sortedNumbers = numbers.sort() | |
if (sortedNumbers.size() % 2 == 0 /* size is even */) { | |
def middleElementIndex = (sortedNumbers.size() / 2 as Integer) - 1 /* - 1 because indices in java for arrays and collections are zero based */ | |
return ((sortedNumbers[middleElementIndex] + sortedNumbers[middleElementIndex + 1]) / 2) | |
} else { /* size is odd */ | |
return sortedNumbers[(Math.ceil(sortedNumbers.size() / 2) as Integer) - 1] | |
} | |
} | |
def add(a, b) { | |
a + b | |
} | |
/** | |
* Mean from sorted numbers with lowest and highest 10% percent numbers cut off. (As I have no formal education in stats is there any official name for this? | |
* Or is it usefull at all? I mean it as a more accurate version of mean when there are some value spikes which we want to filter out) | |
*/ | |
def mean80(numbers) { | |
def sortedNumbers = numbers.sort() | |
def tenPercentOfSize = Math.ceil(sortedNumbers.size() * 0.1).toInteger() | |
def eightyPercent = sortedNumbers.grepWithIndex { value, index -> | |
def result = ((index + 1) > tenPercentOfSize) && ((index + 1) <= (numbers.size() - tenPercentOfSize)) | |
/* //uncomment for debugging purposes | |
println " debug line for value: $value, index: $index, numbers.size(): ${numbers.size()}, tenPercentOfSize: ${tenPercentOfSize}, RESULT IS : ${result} ".center(100, "=") | |
println "((index + 1) > tenPercentOfSize) -> ${((index + 1) > tenPercentOfSize)}"; | |
println "((index + 1) <= (numbers.size() - tenPercentOfSize)) -> ${((index + 1) <= (numbers.size() - tenPercentOfSize))}"; | |
println "=" * 100 | |
//*/ | |
return result | |
} | |
eightyPercent.inject(0, this.&add) / eightyPercent.size() | |
} | |
def printStatisticsFor(numbers) { | |
println "Mean: ${mean(numbers)}" | |
println "Mean 80%: ${mean80(numbers)}" | |
println "Median: ${median(numbers)}" | |
} | |
// ------------------- tests / examples ----------------------------- | |
assert [1, 2, 3].mean() == 2 | |
assert [1].mean() == 1 | |
assert [1, 2].mean() == 1.5 | |
assert [1, 2, 3, 4, 5, 6].mean() == 3.5 | |
assert [1, 2, 3].median() == 2 | |
assert [1, 2, 3, 4].median() == 2.5 | |
assert [1].median() == 1 | |
assert [1, 2].median() == 1.5 | |
//printStatisticsFor(1..100) /* prints out basic statistics for from 1 to 100 range */ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment