Skip to content

Instantly share code, notes, and snippets.

@michalbcz
Created August 15, 2012 14:25
Show Gist options
  • Save michalbcz/3360573 to your computer and use it in GitHub Desktop.
Save michalbcz/3360573 to your computer and use it in GitHub Desktop.
groovy - super basic stats and usage of class extensions
// ------------------- 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