Tuesday, January 5, 2010

Groovy: Means, Medians, Modes, and Ranges Calculations

I needed to check a seventh grader's homework related to means, medians, modes, and ranges and Groovy seemed like a nice approach to writing a quick tool to check these calculations. The calculations used in this Groovy script are based on definitions of these terms in Mean, Median, Mode, and Range and in Mean, Median, and Mode: Overview.

I hurriedly put this script, modeMedianMean.groovy, together, so it could probably use some work. However, I wanted to check the homework with a quick and dirty tool and it does provide more examples of using some of Groovy's features and syntax.

modeMedianMean.groovy

#!/usr/bin/env groovy
// Script for calculating median, mean, mode, range, etc.
//
// http://www.purplemath.com/modules/meanmode.htm

if (args.length < 1)
{
println "You need to provide at least one numeric argument."
System.exit(-1)
}

// Place passed-in number arguments in List
values = new ArrayList<BigDecimal>()
for (i in args)
{
try
{
values.add(new BigDecimal(i))
}
catch (NumberFormatException numberFormatEx)
{
println "Ignoring non-numeric parameter: ${i}"
}
}
Collections.sort(values)

// Begin collecting metadata about the data
numberItems = values.size()
sum = 0
modeMap = new HashMap<BigDecimal, Integer>()
for (item in values)
{
sum += item
if (modeMap.get(item) == null)
{
modeMap.put(item, 1)
}
else
{
count = modeMap.get(item) + 1
modeMap.put(item, count)
}
}
mode = new ArrayList<Integer>()
modeCount = 0
modeMap.each()
{ key, value ->
if (value > modeCount) { mode.clear(); mode.add(key); modeCount = value}
else if (value == modeCount) { mode.add(key) }
};
mean = sum / numberItems
midNumber = (int)(numberItems/2)
median = numberItems %2 != 0 ? values[midNumber] : (values[midNumber] + values[midNumber-1])/2
minimum = Collections.min(values)
maximum = Collections.max(values)

println "You provided ${numberItems} numbers (${values}):"
println "\tMean: ${mean}"
println "\tMedian: ${median}"
println "\tMode: ${mode}"
println "\tMinimum: ${minimum}"
println "\tMaximum: ${maximum}"
println "\tRange: ${maximum - minimum}"


The next screen snapshot demonstrates this simple script in action with a variety of different numbers.



The examples demonstrated in the above screen snapshot demonstrated the sort and the basic functionality of median, mode, and mean, but all examples use integral numbers. The next screen snapshot includes some non-integer numbers and also shows the handling (ignored) of non-numeric parameters.



This simple script demonstrates how easy it is to use Groovy to accomplish repetitive tasks. With a little more time and effort, the script could be further improved, but it was sufficient for me to use to quickly check the seventh grade homework.

No comments: