From d2ce00de04b275fb49d5c521abceab709a374b06 Mon Sep 17 00:00:00 2001 From: Tim Yates Date: Mon, 25 Nov 2013 12:23:33 +0000 Subject: [PATCH] v0.5.5 Bugfix for 0 length collections --- README.md | 2 +- build.gradle | 2 +- .../CollectionExtensionMethods.groovy | 29 ++++++++++--------- src/test/groovy/tests/CollectionTests.groovy | 14 +++++++-- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 53d7faf..76e3c2e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Obviously requires at least Groovy 2.0.5 (so that the extension system exists) Usage: - @Grab( 'com.bloidonia:groovy-common-extensions:0.5.4' ) + @Grab( 'com.bloidonia:groovy-common-extensions:0.5.5' ) and the following methods will be available to you: diff --git a/build.gradle b/build.gradle index dc8c6bb..195d983 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ apply plugin: 'signing' sourceCompatibility=1.6 targetCompatibility=1.6 -version = '0.5.4' +version = '0.5.5' repositories { mavenCentral() diff --git a/src/main/groovy/com/bloidonia/groovy/extensions/CollectionExtensionMethods.groovy b/src/main/groovy/com/bloidonia/groovy/extensions/CollectionExtensionMethods.groovy index 98b9fbf..3891926 100644 --- a/src/main/groovy/com/bloidonia/groovy/extensions/CollectionExtensionMethods.groovy +++ b/src/main/groovy/com/bloidonia/groovy/extensions/CollectionExtensionMethods.groovy @@ -273,11 +273,11 @@ class CollectionExtensionMethods { } @groovy.transform.Immutable( knownImmutables=[ 'median' ]) - public static class AverageStats { - Double mean - V median - Double variance - Double stdDev + public static class AverageStats { + BigDecimal mean + BigDecimal median + BigDecimal variance + BigDecimal stdDev String toString() { "AverageStats( mean:$mean, median:$median, variance:$variance, stdDev:$stdDev )" @@ -300,15 +300,18 @@ class CollectionExtensionMethods { * @param collection The {@code Collection} of {@code Number} elements to generate stats for * @return A populated {@code AverageStats} object */ - static AverageStats average( Collection collection ) { + static AverageStats average( Collection collection ) { int size = collection.size() - V sum = collection.sum() - int zsize = size - 1 - V median = size % 2 == 1 ? - collection.sort( false )[ ( zsize / 2 ).toInteger() ] : - collection.sort( false )[ [ Math.floor( zsize / 2 ), Math.ceil( zsize / 2.0 ) ]*.toInteger() ].sum() / 2 - double mean = sum / size - double variance = 0 + if( size == 0 ) { + return new AverageStats( mean: 0, median: 0, variance: 0, stdDev: 0 ) + } + V sum = collection.sum() + int zsize = size - 1 + BigDecimal median = size % 2 == 1 ? + collection.sort( false )[ ( zsize / 2 ).toInteger() ] : + collection.sort( false )[ [ Math.floor( zsize / 2 ), Math.ceil( zsize / 2.0 ) ]*.toInteger() ].sum() / 2 + BigDecimal mean = sum / size + BigDecimal variance = 0 for( V num : collection ) { variance += ( mean - num ) * ( mean - num ) diff --git a/src/test/groovy/tests/CollectionTests.groovy b/src/test/groovy/tests/CollectionTests.groovy index b3f2ab5..873f591 100644 --- a/src/test/groovy/tests/CollectionTests.groovy +++ b/src/test/groovy/tests/CollectionTests.groovy @@ -144,7 +144,7 @@ class CollectionTests extends Specification { def avg = [ 332G, 42G, 100G ].average() expect: avg.mean == 158 - avg.median == 100G + avg.median == 100 String.format( '%.7g', avg.variance ) == '15698.67' String.format( '%.6g', avg.stdDev ) == '125.294' } @@ -154,8 +154,18 @@ class CollectionTests extends Specification { def avg = [ 332.0G, 998.0G, 42.0G, 100.0G ].average() expect: avg.mean == 368 - avg.median == 216.0G + avg.median == 216 String.format( '%.7g', avg.variance ) == '144074.0' String.format( '%.6g', avg.stdDev ) == '379.571' } + + def 'check zero length averages'() { + given: + def avg = [].average() + expect: + avg.mean == 0 + avg.median == 0 + avg.variance == 0 + avg.stdDev == 0 + } } \ No newline at end of file