Complete the following exercises:

  1. Consider two functions that compute the following:
    • The arithmetic mean of an array of doubles
    • The median of an array of doubles

    Write unit tests for these functions.

    mean

    • [] -> None (or some exception)
    • [0] -> 0
    • [0, 2] -> 1
    • [-1, 1] -> 0
    • [0, 1, 2, 3, 4] -> 5

    median

    • [] -> None (or some exception)
    • [0] -> 0
    • [0, 2] -> 1
    • [-1, 1] -> 0
    • [0, 1, 2, 3, 4] -> 2
  2. Compare your (black box) test cases to those developed by others. Did you miss any important test cases?

  3. Write C or Java code for the aforementioned functions. You may not use any library functions in your implementation.

    /**
     * Calculate and print the median of a set of values.
     */
    public class Median {
      public static void main(String[] args) {
        // convert the arguments to double
        final double[] values = new double[args.length];
        for (int i = 0; i < values.length; i++) {
          final String arg = args[i];
    
          final double value = Double.parseDouble(arg);
          values[i] = value;
        }
    
        final double median = median(values);
        System.out.printf("The median is %.3f%n", median);
      }
    
      /**
       * Compute the arithmetic mean of an array of <code>double</code>s.
       */
      public static double mean(final double[] values) {
        // compute the mean of the entire array
        return mean(values, 0, values.length);
      }
    
      /**
       * Computes the arithmetic mean of a slice of an array.
       *
       * @param values array over which to compute the mean
       * @param start lower index of the array slice (inclusive)
       * @param end upper index of the array slice (exclusive)
       */
      private static double mean(final double[] values, int start, int end) {
        double sum = 0.0;
        for (int i = start; i < end; i++) {
          sum += values[i]; // sum the elements of the array
        }
    
        final double mean = sum / (end - start);
        return mean;
      }
    
      /**
       * Compute the median of an array of <code>double</code>s.
       */
      public static double median(final double[] values) {
        if (values.length == 0) {
          final String message = "Median not defined for an empty array";
          throw new IllegalArgumentException(message);
        }
    
        sort(values); // sort the values
    
        final int midpoint = values.length >> 1; // index of array's midpoint
    
        final double median;
        if ((values.length & 0x01) == 0x01) { // odd number of elements
          median = values[midpoint];
        } else { // even number of elements
          median = mean(values, midpoint - 1, midpoint + 1);
        }
    
        return median;
      }
    
      /**
       * Sort the specified values in ascending order using the insertion sort
       * algorithm.
       */
      private static void sort(double[] values) {
        for (int i = 0; i < values.length; i++) {
          for (int j = i; 0 < j; j--) {
            if (values[j] < values[j - 1]) { // out of order => swap values
              final double tmp = values[j];
              values[j] = values[j - 1];
              values[j - 1] = tmp;
            }
          }
        }
      }
    }
    
  4. Draw the control flow graph (CFG) of each function.

    main
    CFG for main method
    mean
    CFG for mean method
    median
    CFG for median method
    sort
    CFG for sort method
  5. Compute the cyclomatic complexity of each function.

    Function Cyclomatic Number
    main 2
    mean 2
    median 3
    sort 4
  6. Exchange your implementations of the aforementioned functions with someone else. Draw the CFG and calculate the cyclomatic complexity of each function. Verify that your CFG and cyclomatic number matches the original author’s.

  7. While looking at your code, write unit tests for each function. Organize your test cases as follows:
    • the minimum set required to exercise all statements
    • the minimum set required to exercise all branches
    • the minimum set required to exercise all paths