Fields 0 / 2 -are there 2 fields for the default minimum and maximum? 2 / 2 -are there non-static fields for the minimum and maximum? Constructors 0 / 1 -does the no argument constructor initialize the range correctly? 1 / 1 -does the constructor throw the correct exception when required? 1 / 1 -does the constructor initialize the range correctly? 1 / 1 -does the copy constructor copy the other range correctly? Methods -getMinimum 1 / 1 -returns the correct value? -getMaximum 1 / 1 -returns the correct value? -setDefaultMinimum 0 / 1 -sets the default minimum when it should? -setDefaultMaximum 0 / 1 -sets the default maximum when it should? -contains 1 / 2 -returns the correct value? -overlaps 0 / 2 -returns the correct value? -centeredAt 0 / 2 -returns the correct range? -------------------- TA Comments: -minValue and maxValue should be private -you need two static fields to store the default minimum and maximum range values -the no-argument constructor should use the missing static fields to set the minimum and maximum values of this range -setDefaultMinimum and setDefaultMaximum should set the missing static fields -in contains: return value > this.minValue && value < this.maxValue; should be return value >= this.minValue && value <= this.maxValue; -overlaps: public boolean overlaps(Range other) { return this.contains(other.getMinimum()) || this.contains(other.getMaximum()) || other.contains(this.getMinimum()) || other.contains(this.getMaximum()); } -centeredAt: public static Range centeredAt(double value, double width) { double half = width / 2; return new Range(value - half, value + half); } -------------------- Unit tester output: YOUR SUMBISSION FAILED SOME UNIT TESTS Here is the test output: java -classpath .:/home/burton/work/teaching/2017F/2030/marking/secEtest2D/_jar/* org.junit.runner.JUnitCore test2.Test2Suite JUnit version 4.12 .E..E.E...E.E.E.E..E Time: 0.024 There were 8 failures: 1) test01_staticFields(test2.RangeTest) java.lang.AssertionError: there should be at least 4 static fields 2) test03_noArgCtor(test2.RangeTest) java.lang.StackOverflowError 3) test04_ctorThrows(test2.RangeTest) java.lang.AssertionError: constructor should have thrown an IllegalArgumentException 4) test07_setDefaultMin(test2.RangeTest) java.lang.StackOverflowError 5) test08_setDefaultMax(test2.RangeTest) java.lang.AssertionError: no arg ctor is not using the new default min expected:<-1000.0> but was:<0.0> 6) test09_contains(test2.RangeTest) java.lang.AssertionError: contains(this.min) should be true 7) test10_overlaps(test2.RangeTest) java.lang.AssertionError: overlaps should be true 8) test12_centeredAt(test2.RangeTest) java.lang.NullPointerException FAILURES!!! Tests run: 12, Failures: 8 -------------------- Your submission: package test2; /** * A class that represents a range of values on the real number line. * A range has two properties: a minimum value and a maximum value. * Range objects always ensure that the following class invariant is true: * <br><br> * * <pre> * minimum value of this range is less than or equal to the maximum * value of this range * </pre> * * <p> * The no-argument constructor creates a range using the default minimum * and maximum values; the initial minimum and maximum values are * defined by the <code>final</code> values * <code>Range.INITIAL_DEFAULT_MIN</code> and * <code>Range.INITIAL_DEFAULT_MAX</code>. Clients are able to * change the default values (but not the initial default values) * using the methods <code>setDefaultMinimum</code> and * <code>setDefaultMaximum</code>. * */ public class Range { /** * The initial default minimum value of the Range class. */ public static final double INITIAL_DEFAULT_MIN = 0; /** * The initial default maximum value of the Range class. */ public static final double INITIAL_DEFAULT_MAX = 100; public double minValue; public double maxValue; /** * Initialize this range so that its minimum and maximum values * are equal to the default minimum and maximum values of the * Range class. */ public Range() { this.minValue = INITIAL_DEFAULT_MIN; this.maxValue = INITIAL_DEFAULT_MAX; } /** * Create a range with the specified minimum and maximum values. * * @param min * the minimum value of the range * @param max * the maximum value of the range * @throws IllegalArgumentException * if min is greater than max */ public Range(double min, double max) { this.minValue = min; this.maxValue = max; } /** * Initializes this range so that its minimum and maximum values are equal * to the minimum and maximum values of the specified other range. * * @param other * a range */ public Range(Range other) { this.minValue = other.minValue; this.maxValue = other.maxValue; } /** * Returns the minimum value of the range * * @return the minimum value of the range */ public double getMinimum() { return this.minValue; } /** * Returns the maximum value of the range * * @return the maximum value of the range */ public double getMaximum() { return this.maxValue; } /** * Set the default minimum value of the Range class to * the specified value. If the specified value is greater * than the default maximum value of the Range class then * the default minimum value is not changed by this method * (and no exception is thrown). * * @param min the new default minimum value for the Range class */ public static void setDefaultMinimum(double min) { if (min < Range.INITIAL_DEFAULT_MAX) { Range.setDefaultMinimum(min); } } /** * Set the default maximum value of the Range class to * the specified value. If the specified value is less * than the default minimum value of the Range class then * the default maximum value is not changed by this method * (and no exception is thrown). * * @param max the new default maximum value for the Range class */ public static void setDefaultMaximum(double max) { if (max < Range.INITIAL_DEFAULT_MIN){ Range.setDefaultMaximum(max); } } /** * Checks if <code>value</code> is inside this range. A value is considered * inside this range if the value is greater than or equal to the minimum * value of this range and the value is less than or equal to the maximum * value of this range. * * @param value * the value to check * @return true if value is inside this range, and false otherwise */ public boolean contains(double value) { return value > this.minValue && value < this.maxValue; } /** * Checks if this range overlaps with another range. Two ranges overlap if * at least one <code>double</code> value is contained by both ranges. For * example, the two ranges * * <p> * <code>[0.1, 0.8]</code> and <code>[0.6, 2.5]</code> overlap because all * values between <code>0.6</code> and <code>0.8</code> are contained by * both ranges. * * <p> * The two ranges * * <p> * <code>[-0.25, 0.33]</code> and <code>[0.33, 1.0]</code> overlap because * both ranges contain the value <code>0.33</code> * * * @param other * the other range to check * @return true if this range overlaps with other, and false otherwise. */ public boolean overlaps(Range other) { return this.minValue >= other.minValue && this.minValue <= other.minValue || (this.maxValue >= other.minValue && this.maxValue <= other.maxValue); } /** * Return a new range that is centered at <code>value</code> and whose total * width is <code>width</code>. For example: * * <p> * <code>Range.centeredAt(10.0, 5.0)</code> * * <p> * would return the range <code>[7.5, 12.5]</code>. * * * @param value * the center of the desired range * @param width * the total width of the desired range * @return a new Range of the specified width centered at the specified * value * @pre. width is greater than or equal to zero */ public static Range centeredAt(double value, double width) { return null; } } -------------------- Written answers marking scheme A 2 / 2 is a suitable definition given? B 0 / 1 no this is not a good implementation? 0 / 2 is there a suitable explanation? C 0 / 1 incorrect signature? 0 / 1 check for null before using obj.getClass()? 0 / 1 && should be || ? 0 / 2 x.equals(null) does not return false D 2 / 2 constructor chaining? -------------------- TA Comments B. No, the implementation of compareTo is not transitive. Consider the following: Range x = new Range(1.0, 2.0); Range y = new Range(1.9, 3.0); // overlaps with x between 1.9 and 2.0 Range z = new Range(2.9, 4.0); // overlaps with y between 2.9 and 2.0 int xy = x.compareTo(y); // returns 0 int yz = y.compareTo(z); // returns 0 int xz = x.compareTo(z); // returns -1 oops, not transitive C (a) 1. the signature is incorrect (parameter has type Range instead of Object) 2. must check for null before using obj.getClass() 3. the && should be || C (b) equals does not check for transitiviy or that x.equals(y) returns the same result if x and y don't change. The implementation is supposed to guarantee that these things don't happen. No, x.equals(null) does not return false (it throws a NullPointerException when obj.getClass() is called if obj is null). -------------------- Your submission: A. The keyword final means that the field can only be assigned a value one time. Does not mean that it is a constant. B. Yes, this is a good implementation of compareTo, since it allows you to compare the relative size/order of 2 objects, which is a Range in this case, to see if one is smaller than the other, bigger than the other, or equal to each other. C. While there are no errors in the implementation, not all parts of the equals contract are satisfied. One part of the contact that is not tested is that if x.equals(y) and y.equals(z) is true, then x.equals(z) must also be true. Also, x.equals(y) stays in the same state if the fields were not changed. D. when a constructor invokes another constructor of the same class, it is known as constructor chaining. --------------------