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
  1. #!/usr/bin/env groovy  
  2. // Script for calculating median, mean, mode, range, etc.  
  3. //  
  4. // http://www.purplemath.com/modules/meanmode.htm  
  5.   
  6. if (args.length < 1)  
  7. {  
  8.    println "You need to provide at least one numeric argument."  
  9.    System.exit(-1)  
  10. }  
  11.   
  12. // Place passed-in number arguments in List  
  13. values = new ArrayList<BigDecimal>()  
  14. for (i in args)  
  15. {  
  16.    try  
  17.    {  
  18.       values.add(new BigDecimal(i))  
  19.    }  
  20.    catch (NumberFormatException numberFormatEx)  
  21.    {  
  22.       println "Ignoring non-numeric parameter: ${i}"  
  23.    }  
  24. }  
  25. Collections.sort(values)  
  26.   
  27. // Begin collecting metadata about the data  
  28. numberItems = values.size()  
  29. sum = 0  
  30. modeMap = new HashMap<BigDecimal, Integer>()  
  31. for (item in values)  
  32. {  
  33.    sum += item  
  34.    if (modeMap.get(item) == null)  
  35.    {  
  36.       modeMap.put(item, 1)  
  37.    }  
  38.    else  
  39.    {  
  40.       count = modeMap.get(item) + 1  
  41.       modeMap.put(item, count)  
  42.    }  
  43. }  
  44. mode = new ArrayList<Integer>()  
  45. modeCount = 0  
  46. modeMap.each()  
  47.    { key, value ->   
  48.        if (value > modeCount) { mode.clear(); mode.add(key); modeCount = value}  
  49.        else if (value == modeCount) { mode.add(key) }  
  50.    };  
  51. mean = sum / numberItems  
  52. midNumber = (int)(numberItems/2)  
  53. median = numberItems %2 != 0 ? values[midNumber] : (values[midNumber] + values[midNumber-1])/2   
  54. minimum = Collections.min(values)  
  55. maximum = Collections.max(values)  
  56.   
  57. println "You provided ${numberItems} numbers (${values}):"  
  58. println "\tMean: ${mean}"  
  59. println "\tMedian: ${median}"  
  60. println "\tMode: ${mode}"  
  61. println "\tMinimum: ${minimum}"  
  62. println "\tMaximum: ${maximum}"  
  63. 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: