Assignment 5, due Sep 22

Solutions

Part of the homework for CS:2820, Fall 2017
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

  1. Background: Here's a small shell script that compares two files:
    #!/bin/sh # compare f1 f2 # script to compare and comment on differences between 2 files echo comparing $1 with $2 if diff $1 $2; then echo true else echo false fi

    If you store this script in a file called compare and make that file executable with chmod +x compare, you can run it with ./compare f1 f2 for any 2 files f1 and f2. (Try it with small files.) Note, in the script, $1 is a reference to the first command line argument, and $2 is a reference to the second. This is really bad language design, but it works, so we live with it.

    a) Does the diff command return an idication of success or failure? If so, when does it indicate success and when does it indicate failure. The above script lets you test this empirically. (0.5 points)

    The diff command succeeds if there are no differences and fails if there are differences.

    b) In the notes for Lecture 8, the test file was threatening to get very long by the end. Suggest a script that could be used in the test script in order to allow each test to be coded on one line, assuming that there were existing files holding the input, the expected output, and the expected error messages for each test, stored in the testfiles directory. (0.5 points)

    Here is a useful script, stored in a file called test that has been marked as executable:

    #!/bin/sh
    # test command outfile errfile errmsg
    # script to run command with given input and test outputs against expected
    $1 > actualoutfile 2> actualerrfile
    if ! diff $2 actualoutfile; then
            echo $4 ": standard output differs"
    fi
    if ! diff $3 actualerrfile; then
            echo $4 ": standard error differs"
    fi
    rm actualerrfile actualoutfile
    

    A script to test the road network program using the above script might look like this, taking advantage of the fact that the special file /dev/null is an empty file. The assignment did not ask for this detail, but it may help you to understand the above test script if you see how it is used:

    #!/bin/sh
    ./test "java RoadNetwork" /dev/null test1error "test1 (missing infile)"
    ./test "java RoadNetwork x y" /dev/null test2error "test2 (too many args)"
    ./test "java RoadNetwork gribble" /dev/null test3error "test3 (can't open file)"
    ./test "java RoadNetwork /dev/null" /dev/null /dev/null "test3 (empty infile)"
    ./test "java RoadNetwork test4infile" test4outfile /dev/null "test4 (whatever)"
    

  2. Background: An input file for MP2 contained in a file named f is given as an example at the start of the assignment for MP2. Make reasonable assumptions about the print routine you include in your code for MP2.

    A problem: What output would you expect from your solution to MP2 when given this input? (1.0 points)

    gate A and 1.0
    gate B or 0.5
    gate C neg 0.5
    wire A out B in1 0.1
    wire B out A in1 0.3
    wire A out C in 0.1
    wire C out B in2 0.1
    

    It output all the gates in the order they were declared, and then it output all the wires, in the order they were given. No comments or blank lines were output. This explanatory text is unneeded.

  3. Background: There are two sensible options that a constructor or factory method could use to report failure. It could throw an exception, or in the case of a factory method, it could return null. Look at the code distributed with the Sept. 14 lecture notes, in the readNetwork method. This code contains the line:
    inters.add( new Intersection( sc ) );
    

    What we want, with either solution, is to not-only not create a new intersection, but not add anything to the list inters.

    a) Rewrite this line so that it handles the Intersection.ConstructorFailure exception thrown by the constructor. (0.5 points)

    try {
        inters.add( new Intersection( sc ) );
    } catch (Intersection.ConstructorFailure e) {
    }
    

    b) Rewrite this line so that it handles a return value of null from a call to a factory method that replaces new Intersection(). (0.5 points)

    Intersection i = Intersection.Factory( sc );
    if (i != null) {
        inters.add( i );
    }
    

    The point of the above comparison is that throwing an exception produces code that is no easier to understand than returning null. Both approaches work, both approaches are a bit ugly looking.