Part II, Exercises

exercise No. 169

A command line version computing a sample's average and median Create comment in forum

Q:

This exercise extends the section called “Providing statistical data” by adding a command line interface. Consider the following console execution:

goik >java -jar statistics-1.0.jar 2 6 7
Your sample's average is: 5.0
Your sample's median is: 6.0

The above example executes our Java program in a shell and supplies three command line parameters 2, 6 and 7. The program then executes and creates the desired statistical data.

The subsequent remarks may assist you creating an implementation:

  1. Using command line values means entering strings rather then e.g. integer values: In the current example the Java runtime will pass an array of strings {"2", "6", "7"} on behalf of the user's input 2 6 7 to your main(String [] args) method. These strings must be converted to integer values. This may be achieved by means of parseInt(String).

    Depending on inconsistent user input like three instead of 3 you may decide to terminate your application thereby providing a meaningful error message:

    goik >java -jar statistics-1.0.jar 1 2 three
    Input string 'three' does not represent an integer value
  2. If the user does not provide any input at all our program shall terminate as well:

    goik >java -jar statistics-1.0.jar
    No values provided
  3. Provide an public enum ErrorState definition representing all three possible error states:

    OK:

    No error, all user input strings represent integer values.

    NO_VALUE:

    Error: No user input at all.

    NO_INTEGER:

    Error: At least one input value does not represent an integer value.

  4. Implement a class InputValidator to validate user input and thereby converting string values to an integer array of equal size:

    /**
     * Validate sample input strings and convert
     * them to integer values.
     */
    public class InputValidator {
    
      /**
       * Integer values being calculated upon
       * constructor call.
       */
      public final int[] values;
    
      /**
       * Transform a series of strings into integer values. In case
       * of invalid input, a corresponding error messsage will be written
       * to System.err and the current application will terminate by calling
       * {@link System#exit(int)}. Example: The array ["-1", "20", "three"]
       * contains two valid elements and the invalid element "three" which
       * cannot be converted to an integer value by virtue of
       * {@link Integer#parseInt(String)}.
       *
       * @param userInput A set of strings possibly representing integer values.
       */
      public InputValidator(final String[] userInput) {...}
    }

    You may then create an instance by supplying your main(String[] args) command line values:

    public static void main(String[] args) {
    
      final InputValidator userInput = new InputValidator(args);
    ...

    Choose your implementation with testing in mind.

  5. Write at least one test case for all three possible error categories and check for correct behaviour of your InputValidator class.

  6. Use your class IntegerStore from exercise the section called “Providing statistical data” to compute the desired output.

  7. Simulating command line arguments in Eclipse requires a run time configuration. Click Run Run Configurations.... Choose Java Applications and "new launch configuration" from the panel's left side, choose your project and main class (if not already selected).

    Select the Arguments tab. Enter your desired command line values, hit Apply and subsequently Run to launch your application.

  8. Maven projects allow for creation of executable jar archives. This leverages the process being described in Creating an Executable jar File. It avoids messing with manifest files and zipping up archives manually.

    Among several configuration possibilities you may use the Maven JAR Plugin and its package goal. You have to add this plugin to the <plugins> section of your pom.xml file. The plugin in turn requires defining the fully qualified name of your entry class ❶ containing the desired main(String[] args) method:

    ...
    <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <javadocDestdir>~/tmp</javadocDestdir>
    </properties>
    
    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-jar-plugin</artifactId>
          <version>2.4</version>
          <configuration>
            <archive>
              <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>de.hdm_stuttgart.mi.sd1.statistics.main.Statistics</mainClass>
                                                                  </manifest>
            </archive>
          </configuration>
        </plugin>
      </plugins>
    </build>
    ...

    Creating the actual jar archive may be triggered by either of:

    From the command line:

    Change to your project root containing your pom.xml file and execute mvn package.

    From inside Eclipse:

    Create a maven run time configuration (see above) containing your package goal:

    After creating the jar archive you may now run your program in a shell as being described in 1 of this section.

A: