package ?????; import java.util.ArrayList; import java.util.Iterator; import java.util.Collections; import java.util.HashMap; public class DStatUtil { // insert OVERVIEW specification here // The following code breaks the idea of procedural abstraction // as we have developed it. // The following code would force creating an instance of DStatUtil. // This seems wrong. Note that it might even be worse to declare // nums to be static. Identify the reasons for each of these points. // Rewrite the class to avoid the problems. What you want to be // able to do is pass the data of the required type to the static // method. Since nums is an ArrayList, might this be a requirement? // Could the code be modified for arrays? Might some of the methods // ddefined below work sensibly for Strings? If so, what modifications // would be needed? public ArrayList nums; public DStatUtil(ArrayList someNums){ nums = new ArrayList(someNums); } public DStatUtil(double[] someNums){ nums = new ArrayList(someNums.length); for (int index=0; index < someNums.length; index++){ nums.add(new Double(someNums[index])); } } // Insert REQUIRES, MODIFIES, EFFECTS clauses public double getMean (){ // Define mean double sum=0.0; double average=0.0; // note the use of the field instance variable nums. // Can this be simplified. Consider changing the code. Iterator iterator = nums.iterator(); while(iterator.hasNext()) sum = sum + ((Double)iterator.next()).doubleValue(); average = sum / nums.size(); return average; } // Insert REQUIRES, MODIFIES, EFFECTS clauses public ArrayList getRange (){ // Find the range. Returns a tuple with the minimum, // maximum, and range value double min, max; ArrayList ranges; // Again note the use of the field variable nums min = ((Double)Collections.min(nums)).doubleValue(); max = ((Double)Collections.max(nums)).doubleValue(); ranges = new ArrayList(); ranges.add(new Double (min)); ranges.add(new Double (max)); ranges.add(new Double (max-min)); return ranges; } // Insert REQUIRES, MODIFIES, EFFECTS clauses public double getMedian (){ // Find the Median number // create a duplicate since we are going to modify the // sequence // Noote the there is a modification of nums // This is caused by sort and rectified by makinmg a copy. // What should you do in this case? ArrayList seq = new ArrayList(nums); // sort the list of numbers Collections.sort(seq); double median = 0.0; // to hold the median value int length = seq.size(); // to hold the length of the sequence int index=0; // Check to see if the length is an even number if ( ( length % 2) == 0){ // since it is an even number // add the two middle number together index = length / 2; double m1 = ((Double)seq.get(index-1)).doubleValue(); double m2 = ((Double)seq.get(index)).doubleValue(); median = (m1 + m2) /2.0; } else{ // since it is an odd number // just grab the middle number index = (length / 2); median = ((Double)seq.get(index)).doubleValue(); } return median; } // Insert REQUIRES, MODIFIES, EFFECTS clauses // This is a helper method. In the code it is declared private. // This is an indication that it is a helper and should not // be visible outside of the definition. // If the conversion to procedures is to be accomplished, // how should this be changed? private int countMode(Object object, ArrayList list){ int index = 0; int count = 0; do { index = Collections.binarySearch(list, object); if(index >=0)list.remove(index); count++; } while (index >=0); return count; } // Insert REQUIRES, MODIFIES, EFFECTS clauses public double getMode (){ // Find the number that repeats the most. // make a duplicate copy of the nums argument ArrayList duplicate = new ArrayList(nums); Collections.sort(duplicate); double highest_count = -100; double mode = -100; // back to that nums field variable. Iterator iterator = nums.iterator(); // iterate through nums removing each item out of the duplicate // calculate the highest_count and the mode while(iterator.hasNext()){ double count = 0; Object item = iterator.next(); // Count the number of times the item occurs in the list // If Count is 0 go to the next iteration count = countMode(item, duplicate); if (count == 0) continue; // determine the highest count. The highest counted item is the mode. if (count > highest_count){ highest_count = count; mode = ((Double)item).doubleValue(); } } return mode; } }