You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Phil Steitz <ph...@gmail.com> on 2010/07/05 17:35:25 UTC

Re: svn commit: r960602 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/analysis/interpolation/ main/java/org/apache/commons/math/exception/ main/java/org/apache/commons/math/util/ main/resources/META-INF/localization/ site/xdoc/ tes...


erans@apache.org wrote:
> Author: erans
> Date: Mon Jul  5 14:10:10 2010
> New Revision: 960602
> 
> URL: http://svn.apache.org/viewvc?rev=960602&view=rev
> Log:
> MATH-361
> MATH-382

In the future, please separate commits if possible for separate
issues.  In this case, a bug was fixed and some exception
refactoring was also introduced.  These should be separate commits
and changes.xml should be updated with entries for each.

It would be great to discuss the exception refactoring some more.
The commit below gives some concrete examples.  I would like to
understand better why "NumberIsTooLargeException" and
"NumberIsTooSmallException" are better abstractions than more
domain-specific ones.  Also, are we not losing information in stack
traces when we do:

>          if (x.length < 2) {
> -            throw
MathRuntimeException.createIllegalArgumentException(
> -                  LocalizedFormats.WRONG_NUMBER_OF_POINTS, 2,
x.length);
> +            throw new NumberIsTooSmallException(x.length, 2, true);

Perhaps another parameter identifying the quantity that is "too
large" is needed?

Phil





> 
> Added:
>     commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NumberIsTooLargeException.java   (with props)
>     commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NumberIsTooSmallException.java   (with props)
>     commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NumberIsTooLargeExceptionTest.java   (with props)
>     commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NumberIsTooSmallExceptionTest.java   (with props)
> Modified:
>     commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.java
>     commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolator.java
>     commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/LinearInterpolator.java
>     commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.java
>     commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.java
>     commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/SplineInterpolator.java
>     commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NotPositiveException.java
>     commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NotStrictlyPositiveException.java
>     commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/LocalizedFormats.java
>     commons/proper/math/trunk/src/main/resources/META-INF/localization/LocalizedFormats_fr.properties
>     commons/proper/math/trunk/src/site/xdoc/changes.xml
>     commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/LinearInterpolatorTest.java
>     commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/SplineInterpolatorTest.java
>     commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NotPositiveExceptionTest.java
>     commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NotStrictlyPositiveExceptionTest.java
> 
> Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.java?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.java (original)
> +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolatingFunction.java Mon Jul  5 14:10:10 2010
> @@ -18,7 +18,8 @@ package org.apache.commons.math.analysis
>  
>  import org.apache.commons.math.util.LocalizedFormats;
>  import org.apache.commons.math.util.MathUtils;
> -import org.apache.commons.math.MathRuntimeException;
> +import org.apache.commons.math.exception.NoDataException;
> +import org.apache.commons.math.exception.OutOfRangeException;
>  import org.apache.commons.math.FunctionEvaluationException;
>  import org.apache.commons.math.DimensionMismatchException;
>  import org.apache.commons.math.analysis.BivariateRealFunction;
> @@ -85,8 +86,9 @@ public class BicubicSplineInterpolatingF
>       * every grid point.
>       * @throws DimensionMismatchException if the various arrays do not contain
>       * the expected number of elements.
> -     * @throws IllegalArgumentException if {@code x} or {@code y} are not strictly
> +     * @throws NonMonotonousSequenceException if {@code x} or {@code y} are not strictly
>       * increasing.
> +     * @throws NoDataException if any of the arrays has zero length.
>       */
>      public BicubicSplineInterpolatingFunction(double[] x,
>                                                double[] y,
> @@ -99,7 +101,7 @@ public class BicubicSplineInterpolatingF
>          final int yLen = y.length;
>  
>          if (xLen == 0 || yLen == 0 || f.length == 0 || f[0].length == 0) {
> -            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.NO_DATA);
> +            throw new NoDataException();
>          }
>          if (xLen != f.length) {
>              throw new DimensionMismatchException(xLen, f.length);
> @@ -158,15 +160,11 @@ public class BicubicSplineInterpolatingF
>      public double value(double x, double y) {
>          final int i = searchIndex(x, xval);
>          if (i == -1) {
> -            throw MathRuntimeException.createIllegalArgumentException(
> -                  LocalizedFormats.OUT_OF_RANGE_SIMPLE,
> -                  x, xval[0], xval[xval.length - 1]);
> +            throw new OutOfRangeException(x, xval[0], xval[xval.length - 1]);
>          }
>          final int j = searchIndex(y, yval);
>          if (j == -1) {
> -            throw MathRuntimeException.createIllegalArgumentException(
> -                  LocalizedFormats.OUT_OF_RANGE_SIMPLE,
> -                  y, yval[0], yval[yval.length - 1]);
> +            throw new OutOfRangeException(y, yval[0], yval[yval.length - 1]);
>          }
>  
>          final double xN = (x - xval[i]) / (xval[i + 1] - xval[i]);
> @@ -233,13 +231,11 @@ public class BicubicSplineInterpolatingF
>  
>          final int i = searchIndex(x, xval);
>          if (i == -1) {
> -            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.OUT_OF_RANGE_SIMPLE,
> -                                                                      x, xval[0], xval[xval.length - 1]);
> +            throw new OutOfRangeException(x, xval[0], xval[xval.length - 1]);
>          }
>          final int j = searchIndex(y, yval);
>          if (j == -1) {
> -            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.OUT_OF_RANGE_SIMPLE,
> -                                                                      y, yval[0], yval[yval.length - 1]);
> +            throw new OutOfRangeException(y, yval[0], yval[yval.length - 1]);
>          }
>  
>          final double xN = (x - xval[i]) / (xval[i + 1] - xval[i]);
> @@ -376,12 +372,10 @@ class BicubicSplineFunction
>       */
>      public double value(double x, double y) {
>          if (x < 0 || x > 1) {
> -            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.OUT_OF_RANGE_SIMPLE,
> -                                                                      x, 0, 1);
> +            throw new OutOfRangeException(x, 0, 1);
>          }
>          if (y < 0 || y > 1) {
> -            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.OUT_OF_RANGE_SIMPLE,
> -                                                                      y, 0, 1);
> +            throw new OutOfRangeException(y, 0, 1);
>          }
>  
>          final double x2 = x * x;
> 
> Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolator.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolator.java?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolator.java (original)
> +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/BicubicSplineInterpolator.java Mon Jul  5 14:10:10 2010
> @@ -17,7 +17,7 @@
>  package org.apache.commons.math.analysis.interpolation;
>  
>  import org.apache.commons.math.DimensionMismatchException;
> -import org.apache.commons.math.MathRuntimeException;
> +import org.apache.commons.math.exception.NoDataException;
>  import org.apache.commons.math.MathException;
>  import org.apache.commons.math.util.LocalizedFormats;
>  import org.apache.commons.math.util.MathUtils;
> @@ -40,7 +40,7 @@ public class BicubicSplineInterpolator
>                                                            final double[][] fval)
>          throws MathException, IllegalArgumentException {
>          if (xval.length == 0 || yval.length == 0 || fval.length == 0) {
> -            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.NO_DATA);
> +            throw new NoDataException();
>          }
>          if (xval.length != fval.length) {
>              throw new DimensionMismatchException(xval.length, fval.length);
> 
> Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/LinearInterpolator.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/LinearInterpolator.java?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/LinearInterpolator.java (original)
> +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/LinearInterpolator.java Mon Jul  5 14:10:10 2010
> @@ -16,10 +16,11 @@
>   */
>  package org.apache.commons.math.analysis.interpolation;
>  
> -import org.apache.commons.math.MathRuntimeException;
> +import org.apache.commons.math.exception.DimensionMismatchException;
> +import org.apache.commons.math.exception.NumberIsTooSmallException;
>  import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
>  import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
> -import org.apache.commons.math.util.LocalizedFormats;
> +import org.apache.commons.math.util.MathUtils;
>  
>  /**
>   * Implements a linear function for interpolation of real univariate functions.
> @@ -30,28 +31,26 @@ public class LinearInterpolator implemen
>       * @param x the arguments for the interpolation points
>       * @param y the values for the interpolation points
>       * @return a function which interpolates the data set
> -    */
> +     * @throws DimensionMismatchException if {@code x} and {@code y}
> +     * have different sizes.
> +     * @throws NonMonotonousSequenceException if {@code x} is not sorted in
> +     * strict increasing order.
> +     * @throws NumberIsTooSmallException if the size of {@code x} is smaller
> +     * than 2.
> +     */
>      public PolynomialSplineFunction interpolate(double x[], double y[]) {
>          if (x.length != y.length) {
> -            throw MathRuntimeException.createIllegalArgumentException(
> -                  LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, x.length, y.length);
> +            throw new DimensionMismatchException(x.length, y.length);
>          }
>  
>          if (x.length < 2) {
> -            throw MathRuntimeException.createIllegalArgumentException(
> -                  LocalizedFormats.WRONG_NUMBER_OF_POINTS, 2, x.length);
> +            throw new NumberIsTooSmallException(x.length, 2, true);
>          }
>  
>          // Number of intervals.  The number of data points is n + 1.
>          int n = x.length - 1;
>  
> -        for (int i = 0; i < n; i++) {
> -            if (x[i] >= x[i + 1]) {
> -                throw MathRuntimeException.createIllegalArgumentException(
> -                LocalizedFormats.NOT_STRICTLY_INCREASING_NUMBER_OF_POINTS,
> -                i, i+1, x[i], x[i+1]);
> -            }
> -        }
> +        MathUtils.checkOrder(x);
>  
>          // Slope of the lines between the datapoints.
>          final double m[] = new double[n];
> 
> Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.java?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.java (original)
> +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.java Mon Jul  5 14:10:10 2010
> @@ -22,7 +22,7 @@ import java.util.List;
>  import java.util.Map;
>  
>  import org.apache.commons.math.DimensionMismatchException;
> -import org.apache.commons.math.MathRuntimeException;
> +import org.apache.commons.math.exception.NoDataException;
>  import org.apache.commons.math.analysis.MultivariateRealFunction;
>  import org.apache.commons.math.linear.ArrayRealVector;
>  import org.apache.commons.math.linear.RealVector;
> @@ -142,7 +142,7 @@ public class MicrosphereInterpolatingFun
>       * {@code xval} (equal to {@code n}, the number of interpolation points)
>       * do not match, or the the arrays {@code xval[0]} ... {@code xval[n]},
>       * have lengths different from {@code dimension}.
> -     * @throws IllegalArgumentException if there are no data (xval null or zero length)
> +     * @throws NoDataException if there are no data (xval null or zero length)
>       */
>      public MicrosphereInterpolatingFunction(double[][] xval,
>                                              double[] yval,
> @@ -151,7 +151,7 @@ public class MicrosphereInterpolatingFun
>                                              UnitSphereRandomVectorGenerator rand)
>          throws DimensionMismatchException, IllegalArgumentException {
>          if (xval.length == 0 || xval[0] == null) {
> -            throw MathRuntimeException.createIllegalArgumentException(LocalizedFormats.NO_DATA);
> +            throw new NoDataException();
>          }
>  
>          if (xval.length != yval.length) {
> 
> Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.java?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.java (original)
> +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.java Mon Jul  5 14:10:10 2010
> @@ -17,7 +17,8 @@
>  package org.apache.commons.math.analysis.interpolation;
>  
>  import org.apache.commons.math.MathException;
> -import org.apache.commons.math.MathRuntimeException;
> +import org.apache.commons.math.exception.NotPositiveException;
> +import org.apache.commons.math.exception.NotStrictlyPositiveException;
>  import org.apache.commons.math.analysis.MultivariateRealFunction;
>  import org.apache.commons.math.random.UnitSphereRandomVectorGenerator;
>  import org.apache.commons.math.util.LocalizedFormats;
> @@ -25,7 +26,7 @@ import org.apache.commons.math.util.Loca
>  /**
>   * Interpolator that implements the algorithm described in
>   * <em>William Dudziak</em>'s
> - * <a href="http://www.dudziak.com/microsphere.pdf">MS thesis</a>
> + * <a href="http://www.dudziak.com/microsphere.pdf">MS thesis</a>.
>   * @since 2.1
>   *
>   * @version $Revision$ $Date$
> @@ -59,18 +60,17 @@ public class MicrosphereInterpolator
>       * #MicrosphereInterpolator(int, int)
>       * MicrosphereInterpolator(MicrosphereInterpolator.DEFAULT_MICROSPHERE_ELEMENTS,
>       * MicrosphereInterpolator.DEFAULT_BRIGHTNESS_EXPONENT)}.</p>
> -     * weights of the sample data
>       */
>      public MicrosphereInterpolator() {
>          this(DEFAULT_MICROSPHERE_ELEMENTS, DEFAULT_BRIGHTNESS_EXPONENT);
>      }
>  
>      /** Create a microsphere interpolator.
> -     * @param microsphereElements number of surface elements of the microsphere
> +     * @param microsphereElements number of surface elements of the microsphere.
>       * @param brightnessExponent exponent used in the power law that computes the
> -     * weights of the sample data
> -     * @throws IllegalArgumentException if {@code microsphereElements <= 0}
> -     * or {@code brightnessExponent < 0}
> +     * weights of the sample data.
> +     * @throws NotPositiveException if {@code microsphereElements <= 0}
> +     * or {@code brightnessExponent < 0}.
>       */
>      public MicrosphereInterpolator(final int microsphereElements,
>                                     final int brightnessExponent) {
> @@ -94,31 +94,26 @@ public class MicrosphereInterpolator
>  
>      /**
>       * Set the brightness exponent.
> -     * @param brightnessExponent Exponent for computing the distance dimming
> +     * @param exponent Exponent for computing the distance dimming
>       * factor.
> -     * @throws IllegalArgumentException if {@code brightnessExponent < 0}.
> +     * @throws NotPositiveException if {@code exponent < 0}.
>       */
> -    public void setBrightnessExponent(final int brightnessExponent) {
> -        if (brightnessExponent < 0) {
> -            throw MathRuntimeException.createIllegalArgumentException(
> -                LocalizedFormats.NEGATIVE_BRIGHTNESS_EXPONENT,
> -                brightnessExponent);
> +    public void setBrightnessExponent(final int exponent) {
> +        if (exponent < 0) {
> +            throw new NotPositiveException(exponent);
>          }
> -        this.brightnessExponent = brightnessExponent;
> +        brightnessExponent = exponent;
>      }
>  
>      /**
>       * Set the number of microsphere elements.
>       * @param elements Number of surface elements of the microsphere.
> -     * @throws IllegalArgumentException if {@code microsphereElements <= 0}.
> +     * @throws NotStrictlyPositiveException if {@code elements <= 0}.
>       */
>      public void setMicropshereElements(final int elements) {
> -        if (microsphereElements < 0) {
> -            throw MathRuntimeException.createIllegalArgumentException(
> -                LocalizedFormats.NON_POSITIVE_MICROSPHERE_ELEMENTS,
> -                microsphereElements);
> +        if (elements <= 0) {
> +            throw new NotStrictlyPositiveException(elements);
>          }
> -        this.microsphereElements = elements;
> +        microsphereElements = elements;
>      }
> -
>  }
> 
> Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/SplineInterpolator.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/SplineInterpolator.java?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/SplineInterpolator.java (original)
> +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/SplineInterpolator.java Mon Jul  5 14:10:10 2010
> @@ -16,10 +16,11 @@
>   */
>  package org.apache.commons.math.analysis.interpolation;
>  
> -import org.apache.commons.math.MathRuntimeException;
> +import org.apache.commons.math.exception.DimensionMismatchException;
> +import org.apache.commons.math.exception.NumberIsTooSmallException;
>  import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
>  import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
> -import org.apache.commons.math.util.LocalizedFormats;
> +import org.apache.commons.math.util.MathUtils;
>  
>  /**
>   * Computes a natural (also known as "free", "unclamped") cubic spline interpolation for the data set.
> @@ -55,28 +56,26 @@ public class SplineInterpolator implemen
>       * @param x the arguments for the interpolation points
>       * @param y the values for the interpolation points
>       * @return a function which interpolates the data set
> +     * @throws DimensionMismatchException if {@code x} and {@code y}
> +     * have different sizes.
> +     * @throws NonMonotonousSequenceException if {@code x} is not sorted in
> +     * strict increasing order.
> +     * @throws NumberIsTooSmallException if the size of {@code x} is smaller
> +     * than 3.
>       */
>      public PolynomialSplineFunction interpolate(double x[], double y[]) {
>          if (x.length != y.length) {
> -            throw MathRuntimeException.createIllegalArgumentException(
> -                  LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, x.length, y.length);
> +            throw new DimensionMismatchException(x.length, y.length);
>          }
>  
>          if (x.length < 3) {
> -            throw MathRuntimeException.createIllegalArgumentException(
> -                  LocalizedFormats.WRONG_NUMBER_OF_POINTS, 3, x.length);
> +            throw new NumberIsTooSmallException(x.length, 3, true);
>          }
>  
>          // Number of intervals.  The number of data points is n + 1.
>          int n = x.length - 1;
>  
> -        for (int i = 0; i < n; i++) {
> -            if (x[i] >= x[i + 1]) {
> -                throw MathRuntimeException.createIllegalArgumentException(
> -                      LocalizedFormats.NOT_STRICTLY_INCREASING_NUMBER_OF_POINTS,
> -                      i, i+1, x[i], x[i+1]);
> -            }
> -        }
> +        MathUtils.checkOrder(x);
>  
>          // Differences between knot points
>          double h[] = new double[n];
> 
> Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NotPositiveException.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NotPositiveException.java?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NotPositiveException.java (original)
> +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NotPositiveException.java Mon Jul  5 14:10:10 2010
> @@ -24,13 +24,13 @@ import org.apache.commons.math.util.Loca
>   * @since 2.2
>   * @version $Revision$ $Date$
>   */
> -public class NotPositiveException extends MathIllegalNumberException {
> +public class NotPositiveException extends NumberIsTooSmallException {
>      /**
>       * Construct the exception.
>       *
>       * @param value Argument.
>       */
>      public NotPositiveException(Number value) {
> -        super(LocalizedFormats.NOT_POSITIVE, value);
> +        super(value, 0, true);
>      }
>  }
> 
> Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NotStrictlyPositiveException.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NotStrictlyPositiveException.java?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NotStrictlyPositiveException.java (original)
> +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NotStrictlyPositiveException.java Mon Jul  5 14:10:10 2010
> @@ -24,13 +24,13 @@ import org.apache.commons.math.util.Loca
>   * @since 2.2
>   * @version $Revision$ $Date$
>   */
> -public class NotStrictlyPositiveException extends MathIllegalNumberException {
> +public class NotStrictlyPositiveException extends NumberIsTooSmallException {
>      /**
>       * Construct the exception.
>       *
>       * @param value Argument.
>       */
>      public NotStrictlyPositiveException(Number value) {
> -        super(LocalizedFormats.NOT_STRICTLY_POSITIVE, value);
> +        super(value, 0, false);
>      }
>  }
> 
> Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NumberIsTooLargeException.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NumberIsTooLargeException.java?rev=960602&view=auto
> ==============================================================================
> --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NumberIsTooLargeException.java (added)
> +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NumberIsTooLargeException.java Mon Jul  5 14:10:10 2010
> @@ -0,0 +1,68 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.commons.math.exception;
> +
> +import org.apache.commons.math.util.LocalizedFormats;
> +
> +/**
> + * Exception to be thrown when a number is too large.
> + *
> + * @since 2.2
> + * @version $Revision$ $Date$
> + */
> +public class NumberIsTooLargeException extends MathIllegalNumberException {
> +    /**
> +     * Higher bound.
> +     */
> +    private final Number max;
> +    /**
> +     * Whether the maximum is included in the allowed range.
> +     */
> +    private final boolean boundIsAllowed;
> +
> +    /**
> +     * Construct the exception.
> +     *
> +     * @param wrong Value that is larger than the maximum.
> +     * @param max maximum.
> +     */
> +    public NumberIsTooLargeException(Number wrong,
> +                                     Number max,
> +                                     boolean boundIsAllowed) {
> +        super((boundIsAllowed ?
> +               LocalizedFormats.NUMBER_TOO_LARGE :
> +               LocalizedFormats.NUMBER_TOO_LARGE_BOUND_EXCLUDED),
> +              wrong, max);
> +
> +        this.max = max;
> +        this.boundIsAllowed = boundIsAllowed;
> +    }
> +
> +    /**
> +     * @return {@code true} if the maximum is included in the allowed range.
> +     **/
> +    public boolean getBoundIsAllowed() {
> +        return boundIsAllowed;
> +    }
> +
> +    /**
> +     * @return the maximum.
> +     **/
> +    public Number getMax() {
> +        return max;
> +    }
> +}
> 
> Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NumberIsTooLargeException.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NumberIsTooSmallException.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NumberIsTooSmallException.java?rev=960602&view=auto
> ==============================================================================
> --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NumberIsTooSmallException.java (added)
> +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NumberIsTooSmallException.java Mon Jul  5 14:10:10 2010
> @@ -0,0 +1,68 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.commons.math.exception;
> +
> +import org.apache.commons.math.util.LocalizedFormats;
> +
> +/**
> + * Exception to be thrown when a number is too small.
> + *
> + * @since 2.2
> + * @version $Revision$ $Date$
> + */
> +public class NumberIsTooSmallException extends MathIllegalNumberException {
> +    /**
> +     * Higher bound.
> +     */
> +    private final Number min;
> +    /**
> +     * Whether the maximum is included in the allowed range.
> +     */
> +    private final boolean boundIsAllowed;
> +
> +    /**
> +     * Construct the exception.
> +     *
> +     * @param wrong Value that is smaller than the minimum.
> +     * @param min minimum.
> +     */
> +    public NumberIsTooSmallException(Number wrong,
> +                                     Number min,
> +                                     boolean boundIsAllowed) {
> +        super((boundIsAllowed ?
> +               LocalizedFormats.NUMBER_TOO_SMALL :
> +               LocalizedFormats.NUMBER_TOO_SMALL_BOUND_EXCLUDED),
> +              wrong, min);
> +
> +        this.min = min;
> +        this.boundIsAllowed = boundIsAllowed;
> +    }
> +
> +    /**
> +     * @return {@code true} if the minimum is included in the allowed range.
> +     **/
> +    public boolean getBoundIsAllowed() {
> +        return boundIsAllowed;
> +    }
> +
> +    /**
> +     * @return the minimum.
> +     **/
> +    public Number getMin() {
> +        return min;
> +    }
> +}
> 
> Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/exception/NumberIsTooSmallException.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/LocalizedFormats.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/LocalizedFormats.java?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/LocalizedFormats.java (original)
> +++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/LocalizedFormats.java Mon Jul  5 14:10:10 2010
> @@ -166,8 +166,6 @@ public enum LocalizedFormats implements 
>      NOT_INCREASING_NUMBER_OF_POINTS("points {0} and {1} are not increasing ({2} > {3})"),
>      NOT_INCREASING_SEQUENCE("points {3} and {2} are not increasing ({1} > {0})"), /* keep */
>      NOT_MULTIPLICATION_COMPATIBLE_MATRICES("{0}x{1} and {2}x{3} matrices are not multiplication compatible"),
> -    NOT_STRICTLY_POSITIVE("{0} is not strictly positive"), /* keep */
> -    NOT_POSITIVE("{0} is not positive"), /* keep */
>      NOT_POSITIVE_ALPHA("alpha must be positive ({0})"),
>      NOT_POSITIVE_BETA("beta must be positive ({0})"),
>      NOT_POSITIVE_COLUMNDIMENSION("invalid column dimension: {0} (must be positive)"),
> @@ -219,6 +217,10 @@ public enum LocalizedFormats implements 
>      NULL_OBJECT_TRANSFORMATION("Conversion Exception in Transformation, Object is null"),
>      NULL_REAL_FORMAT("null real format"),
>      NULL_WHOLE_FORMAT("whole format can not be null"),
> +    NUMBER_TOO_LARGE("{0} is larger than the maximum ({1})"), /* keep */
> +    NUMBER_TOO_SMALL("{0} is smaller than the minimum ({1})"), /* keep */
> +    NUMBER_TOO_LARGE_BOUND_EXCLUDED("{0} is larger than, or equal to, the maximum ({1})"), /* keep */
> +    NUMBER_TOO_SMALL_BOUND_EXCLUDED("{0} is smaller than, or equal to, the minimum ({1})"), /* keep */
>      NUMBER_OF_SUCCESS_LARGER_THAN_POPULATION_SIZE("number of successes ({0}) must be less than or equal to population size ({1})"),
>      NUMERATOR_OVERFLOW_AFTER_MULTIPLY("overflow, numerator too large after multiply: {0}"),
>      N_POINTS_GAUSS_LEGENDRE_INTEGRATOR_NOT_SUPPORTED("{0} points Legendre-Gauss integrator not supported, number of points must be in the {1}-{2} range"),
> 
> Modified: commons/proper/math/trunk/src/main/resources/META-INF/localization/LocalizedFormats_fr.properties
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/resources/META-INF/localization/LocalizedFormats_fr.properties?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/main/resources/META-INF/localization/LocalizedFormats_fr.properties (original)
> +++ commons/proper/math/trunk/src/main/resources/META-INF/localization/LocalizedFormats_fr.properties Mon Jul  5 14:10:10 2010
> @@ -138,8 +138,6 @@ NOT_ENOUGH_POINTS_IN_SPLINE_PARTITION = 
>  NOT_INCREASING_NUMBER_OF_POINTS = les points {0} et {1} ne sont pas croissants ({2} > {3})
>  NOT_INCREASING_SEQUENCE = les points {3} et {2} ne sont pas croissants ({1} > {0})
>  NOT_MULTIPLICATION_COMPATIBLE_MATRICES = les dimensions {0}x{1} et {2}x{3} sont incompatibles pour la multiplication matricielle
> -NOT_STRICTLY_POSITIVE = {0} n''est pas strictement positif
> -NOT_POSITIVE = {0} n''est pas positif
>  NOT_POSITIVE_ALPHA = alpha doit \u00eatre positif ({0})
>  NOT_POSITIVE_BETA = beta doit \u00eatre positif ({0})
>  NOT_POSITIVE_COLUMNDIMENSION = nombre de colonnes invalide : {0} (doit \u00eatre positif)
> @@ -191,6 +189,10 @@ NULL_NUMERATOR_FORMAT = le format du num
>  NULL_OBJECT_TRANSFORMATION = Exception de conversion dans une transformation, l''objet est nul
>  NULL_REAL_FORMAT = format r\u00e9el nul
>  NULL_WHOLE_FORMAT = le format complet ne doit pas \u00eatre nul
> +NUMBER_TOO_LARGE = {0} est plus grand que le maximum ({1})
> +NUMBER_TOO_SMALL = {0} est plus petit que le minimum ({1})
> +NUMBER_TOO_LARGE_BOUND_EXCLUDED = {0} n''est pas strictement plus grand que le maximum ({1})
> +NUMBER_TOO_SMALL_BOUND_EXCLUDED = {0} n''est pas strictement plus petit que le minimum ({1})
>  NUMBER_OF_SUCCESS_LARGER_THAN_POPULATION_SIZE = le nombre de succ\u00e8s doit \u00eatre inf\u00e9rieur 
>  NUMERATOR_OVERFLOW_AFTER_MULTIPLY = d\u00e9passement de capacit\u00e9 pour le num\u00e9rateur apr\u00e8s multiplication : {0}
>  N_POINTS_GAUSS_LEGENDRE_INTEGRATOR_NOT_SUPPORTED = l''int\u00e9grateur de Legendre-Gauss en {0} points n''est pas disponible, le nombre de points doit \u00eatre entre {1} et {2}
> 
> Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
> +++ commons/proper/math/trunk/src/site/xdoc/changes.xml Mon Jul  5 14:10:10 2010
> @@ -52,6 +52,9 @@ The <action> type attribute can be add,u
>      If the output is not quite correct, check for invisible trailing spaces!
>       -->
>      <release version="2.2" date="TBD" description="TBD">
> +      <action dev="erans" type="fix" issue="MATH-382">
> +        Fixed bug in precondition check (method "setMicrosphereElements").
> +      </action>
>        <action dev="erans" type="add" issue="MATH-379">
>          Created "MultidimensionalCounter" class.
>        </action>
> 
> Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/LinearInterpolatorTest.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/LinearInterpolatorTest.java?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/LinearInterpolatorTest.java (original)
> +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/LinearInterpolatorTest.java Mon Jul  5 14:10:10 2010
> @@ -17,6 +17,9 @@
>  package org.apache.commons.math.analysis.interpolation;
>  
>  import org.apache.commons.math.MathException;
> +import org.apache.commons.math.exception.NonMonotonousSequenceException;
> +import org.apache.commons.math.exception.DimensionMismatchException;
> +import org.apache.commons.math.exception.NumberIsTooSmallException;
>  import org.apache.commons.math.TestUtils;
>  import org.apache.commons.math.analysis.UnivariateRealFunction;
>  import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
> @@ -109,7 +112,7 @@ public class LinearInterpolatorTest {
>              double yval[] = { 0.0, 1.0, 2.0 };
>              i.interpolate(xval, yval);
>              Assert.fail("Failed to detect data set array with different sizes.");
> -        } catch (IllegalArgumentException iae) {
> +        } catch (DimensionMismatchException iae) {
>              // Expected.
>          }
>          // X values not sorted.
> @@ -118,7 +121,16 @@ public class LinearInterpolatorTest {
>              double yval[] = { 0.0, 1.0, 2.0 };
>              i.interpolate(xval, yval);
>              Assert.fail("Failed to detect unsorted arguments.");
> -        } catch (IllegalArgumentException iae) {
> +        } catch (NonMonotonousSequenceException iae) {
> +            // Expected.
> +        }
> +        // Not enough data to interpolate.
> +        try {
> +            double xval[] = { 0.0 };
> +            double yval[] = { 0.0 };
> +            i.interpolate(xval, yval);
> +            Assert.fail("Failed to detect unsorted arguments.");
> +        } catch (NumberIsTooSmallException iae) {
>              // Expected.
>          }
>      }
> 
> Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/SplineInterpolatorTest.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/SplineInterpolatorTest.java?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/SplineInterpolatorTest.java (original)
> +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/SplineInterpolatorTest.java Mon Jul  5 14:10:10 2010
> @@ -16,20 +16,23 @@
>   */
>  package org.apache.commons.math.analysis.interpolation;
>  
> -import junit.framework.TestCase;
> -
>  import org.apache.commons.math.MathException;
> +import org.apache.commons.math.exception.NonMonotonousSequenceException;
> +import org.apache.commons.math.exception.DimensionMismatchException;
> +import org.apache.commons.math.exception.NumberIsTooSmallException;
>  import org.apache.commons.math.TestUtils;
>  import org.apache.commons.math.analysis.UnivariateRealFunction;
>  import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
>  import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
> +import org.junit.Assert;
> +import org.junit.Test;
>  
>  /**
>   * Test the SplineInterpolator.
>   *
>   * @version $Revision$ $Date$
>   */
> -public class SplineInterpolatorTest extends TestCase {
> +public class SplineInterpolatorTest {
>  
>      /** error tolerance for spline interpolator value at knot points */
>      protected double knotTolerance = 1E-12;
> @@ -40,10 +43,7 @@ public class SplineInterpolatorTest exte
>      /** error tolerance for interpolated values -- high value is from sin test */
>      protected double interpolationTolerance = 1E-2;
>  
> -    public SplineInterpolatorTest(String name) {
> -        super(name);
> -    }
> -
> +    @Test
>      public void testInterpolateLinearDegenerateTwoSegment()
>          throws Exception {
>          double x[] = { 0.0, 0.5, 1.0 };
> @@ -61,11 +61,12 @@ public class SplineInterpolatorTest exte
>          TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance);
>  
>          // Check interpolation
> -        assertEquals(0.0,f.value(0.0), interpolationTolerance);
> -        assertEquals(0.4,f.value(0.4), interpolationTolerance);
> -        assertEquals(1.0,f.value(1.0), interpolationTolerance);
> +        Assert.assertEquals(0.0,f.value(0.0), interpolationTolerance);
> +        Assert.assertEquals(0.4,f.value(0.4), interpolationTolerance);
> +        Assert.assertEquals(1.0,f.value(1.0), interpolationTolerance);
>      }
>  
> +    @Test
>      public void testInterpolateLinearDegenerateThreeSegment()
>          throws Exception {
>          double x[] = { 0.0, 0.5, 1.0, 1.5 };
> @@ -84,11 +85,12 @@ public class SplineInterpolatorTest exte
>          TestUtils.assertEquals(polynomials[2].getCoefficients(), target, coefficientTolerance);
>  
>          // Check interpolation
> -        assertEquals(0,f.value(0), interpolationTolerance);
> -        assertEquals(1.4,f.value(1.4), interpolationTolerance);
> -        assertEquals(1.5,f.value(1.5), interpolationTolerance);
> +        Assert.assertEquals(0,f.value(0), interpolationTolerance);
> +        Assert.assertEquals(1.4,f.value(1.4), interpolationTolerance);
> +        Assert.assertEquals(1.5,f.value(1.5), interpolationTolerance);
>      }
>  
> +    @Test
>      public void testInterpolateLinear() throws Exception {
>          double x[] = { 0.0, 0.5, 1.0 };
>          double y[] = { 0.0, 0.5, 0.0 };
> @@ -105,6 +107,7 @@ public class SplineInterpolatorTest exte
>          TestUtils.assertEquals(polynomials[1].getCoefficients(), target, coefficientTolerance);
>      }
>  
> +    @Test
>      public void testInterpolateSin() throws Exception {
>          double x[] =
>              {
> @@ -151,11 +154,11 @@ public class SplineInterpolatorTest exte
>          TestUtils.assertEquals(polynomials[7].getCoefficients(), target, coefficientTolerance);
>  
>          //Check interpolation
> -        assertEquals(Math.sqrt(2d) / 2d,f.value(Math.PI/4d),interpolationTolerance);
> -        assertEquals(Math.sqrt(2d) / 2d,f.value(3d*Math.PI/4d),interpolationTolerance);
> +        Assert.assertEquals(Math.sqrt(2d) / 2d,f.value(Math.PI/4d),interpolationTolerance);
> +        Assert.assertEquals(Math.sqrt(2d) / 2d,f.value(3d*Math.PI/4d),interpolationTolerance);
>      }
>  
> -
> +    @Test
>      public void testIllegalArguments() throws MathException {
>          // Data set arrays of different size.
>          UnivariateRealInterpolator i = new SplineInterpolator();
> @@ -163,16 +166,27 @@ public class SplineInterpolatorTest exte
>              double xval[] = { 0.0, 1.0 };
>              double yval[] = { 0.0, 1.0, 2.0 };
>              i.interpolate(xval, yval);
> -            fail("Failed to detect data set array with different sizes.");
> -        } catch (IllegalArgumentException iae) {
> +            Assert.fail("Failed to detect data set array with different sizes.");
> +        } catch (DimensionMismatchException iae) {
> +            // Expected.
>          }
>          // X values not sorted.
>          try {
>              double xval[] = { 0.0, 1.0, 0.5 };
>              double yval[] = { 0.0, 1.0, 2.0 };
>              i.interpolate(xval, yval);
> -            fail("Failed to detect unsorted arguments.");
> -        } catch (IllegalArgumentException iae) {
> +            Assert.fail("Failed to detect unsorted arguments.");
> +        } catch (NonMonotonousSequenceException iae) {
> +            // Expected.
> +        }
> +        // Not enough data to interpolate.
> +        try {
> +            double xval[] = { 0.0, 1.0 };
> +            double yval[] = { 0.0, 1.0 };
> +            i.interpolate(xval, yval);
> +            Assert.fail("Failed to detect unsorted arguments.");
> +        } catch (NumberIsTooSmallException iae) {
> +            // Expected.
>          }
>      }
>  
> @@ -182,7 +196,7 @@ public class SplineInterpolatorTest exte
>      protected void verifyInterpolation(UnivariateRealFunction f, double x[], double y[])
>          throws Exception{
>          for (int i = 0; i < x.length; i++) {
> -            assertEquals(f.value(x[i]), y[i], knotTolerance);
> +            Assert.assertEquals(f.value(x[i]), y[i], knotTolerance);
>          }
>      }
>  
> @@ -195,11 +209,11 @@ public class SplineInterpolatorTest exte
>          PolynomialFunction polynomials[] = f.getPolynomials();
>          for (int i = 1; i < x.length - 2; i++) {
>              // evaluate polynomials and derivatives at x[i + 1]
> -            assertEquals(polynomials[i].value(x[i +1] - x[i]), polynomials[i + 1].value(0), 0.1);
> -            assertEquals(polynomials[i].derivative().value(x[i +1] - x[i]),
> -                    polynomials[i + 1].derivative().value(0), 0.5);
> -            assertEquals(polynomials[i].polynomialDerivative().derivative().value(x[i +1] - x[i]),
> -                    polynomials[i + 1].polynomialDerivative().derivative().value(0), 0.5);
> +            Assert.assertEquals(polynomials[i].value(x[i +1] - x[i]), polynomials[i + 1].value(0), 0.1);
> +            Assert.assertEquals(polynomials[i].derivative().value(x[i +1] - x[i]),
> +                                polynomials[i + 1].derivative().value(0), 0.5);
> +            Assert.assertEquals(polynomials[i].polynomialDerivative().derivative().value(x[i +1] - x[i]),
> +                                polynomials[i + 1].polynomialDerivative().derivative().value(0), 0.5);
>          }
>      }
>  
> 
> Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NotPositiveExceptionTest.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NotPositiveExceptionTest.java?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NotPositiveExceptionTest.java (original)
> +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NotPositiveExceptionTest.java Mon Jul  5 14:10:10 2010
> @@ -29,5 +29,7 @@ public class NotPositiveExceptionTest {
>      public void testAccessors() {
>          final NotPositiveException e = new NotPositiveException(-1);
>          Assert.assertEquals(-1, e.getArgument());
> +        Assert.assertEquals(0, e.getMin());
> +        Assert.assertTrue(e.getBoundIsAllowed());
>      }
>  }
> 
> Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NotStrictlyPositiveExceptionTest.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NotStrictlyPositiveExceptionTest.java?rev=960602&r1=960601&r2=960602&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NotStrictlyPositiveExceptionTest.java (original)
> +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NotStrictlyPositiveExceptionTest.java Mon Jul  5 14:10:10 2010
> @@ -29,5 +29,7 @@ public class NotStrictlyPositiveExceptio
>      public void testAccessors() {
>          final NotStrictlyPositiveException e = new NotStrictlyPositiveException(0);
>          Assert.assertEquals(0, e.getArgument());
> +        Assert.assertEquals(0, e.getMin());
> +        Assert.assertFalse(e.getBoundIsAllowed());
>      }
>  }
> 
> Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NumberIsTooLargeExceptionTest.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NumberIsTooLargeExceptionTest.java?rev=960602&view=auto
> ==============================================================================
> --- commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NumberIsTooLargeExceptionTest.java (added)
> +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NumberIsTooLargeExceptionTest.java Mon Jul  5 14:10:10 2010
> @@ -0,0 +1,35 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.commons.math.exception;
> +
> +import org.junit.Assert;
> +import org.junit.Test;
> +
> +/**
> + * Test for {@link NumberIsTooLargeException}.
> + * 
> + * @version $Revision$ $Date$ 
> + */
> +public class NumberIsTooLargeExceptionTest {
> +    @Test
> +    public void testAccessors() {
> +        final NumberIsTooLargeException e = new NumberIsTooLargeException(1, 0, true);
> +        Assert.assertEquals(1, e.getArgument());
> +        Assert.assertEquals(0, e.getMax());
> +        Assert.assertTrue(e.getBoundIsAllowed());
> +    }
> +}
> 
> Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NumberIsTooLargeExceptionTest.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NumberIsTooSmallExceptionTest.java
> URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NumberIsTooSmallExceptionTest.java?rev=960602&view=auto
> ==============================================================================
> --- commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NumberIsTooSmallExceptionTest.java (added)
> +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NumberIsTooSmallExceptionTest.java Mon Jul  5 14:10:10 2010
> @@ -0,0 +1,35 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.commons.math.exception;
> +
> +import org.junit.Assert;
> +import org.junit.Test;
> +
> +/**
> + * Test for {@link NumberIsTooSmallException}.
> + * 
> + * @version $Revision$ $Date$ 
> + */
> +public class NumberIsTooSmallExceptionTest {
> +    @Test
> +    public void testAccessors() {
> +        final NumberIsTooSmallException e = new NumberIsTooSmallException(0, 0, false);
> +        Assert.assertEquals(0, e.getArgument());
> +        Assert.assertEquals(0, e.getMin());
> +        Assert.assertFalse(e.getBoundIsAllowed());
> +    }
> +}
> 
> Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math/exception/NumberIsTooSmallExceptionTest.java
> ------------------------------------------------------------------------------
>     svn:eol-style = native
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: svn commit: r960602 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/analysis/interpolation/ main/java/org/apache/commons/math/exception/ main/java/org/apache/commons/math/util/ main/resources/META-INF/localization/ site/xdoc/ tes...

Posted by Gilles Sadowski <gi...@harfang.homelinux.org>.
> We are at a dead end here. The examples below were use cases I am
> interested in, at least from my point of view. We can probably stop this
> discussion here as you don't even acknowledge the efforts we do to find
> a consensus.

That's not true. And I'm at a complete loss because you don't seem to
understand my point, however I'm explaining it.
You say that you wish to reduce the number of messages/enums but it is
a fact no two of them contain exactly the same information, hence removing
one is, undoubtedly, a loss of information.

The (secondary) argument I was holding is that this loss is not significant
because the message (resulting from a precondition violation) is only
*temporary*: it appears because the program is not robust enough and the
its *real* purpose is to convey to the *developer* (through a bug report)
some hints as what happened and how to correct the problem. The message is
not there so that the user/operator can start to figure out how to work
around the problem. [I know that it could/will be used that way until
the next release but that's not the point.] The point is that in a library
like CM, the exceptions protect the library first (by not even
attempting meaningless computations) and, as a consequence, provide
robustness because the user (of CM) cannot avoid being informed of the
failure.

The primary argument is that in my opinion, the design error handling can be
improved. And, yes, that will make it simpler for developers. Is that bad?
Is that good for end-users? Perhaps they don't care right now (they won't
notice the difference). But if more developers are attracted to a
project because, among other things, it is based on a clear and simple
design, that will be good for end-users (more developers, more code, more
usefulness, ...)
I'm certainly not meaning that my proposal is that great, but it is an area
(however insignificant as compared to the sometimes complex math involved
in CM) where I could be of help.
IMO the (error handling) design is in a dead end. To elaborate on this
picture: We are approaching the dead end's wall but Phil and you want to go
on towards the wall without considering that the best place might be on the
other side of that wall, hence impossible to attain by this route.
Sometimes it is necessary to go back (i.e. loose features). What I proposed
is to emphasize good design and, from there, figure out how to fulfill the
requirements.

If one of the requirements is to keep the exact same amount of information
as we have now in the list of 200+ messages, then I acknowledge that it is
in contradiction with my secondary argument. Let's say I drop it (that's
what I did already in my previous post).
Then we'll have to create a lot of exception classes; in principle, it's not
a problem. [I had just been attempting to avoid it (also because Phil said,
early on, that he didn't want this).]

> [...]

I've read all your comments. I'm happy that some of them were "Yes" but for
the rest it seems that we are playing an endless ping-pong game. Maybe it is
a limitation of the communication medium that makes it look like each of us
gives, to the other, the impression to be out of focus...

So I skip to here, where the same communication problem may be at work:

> > 
> > In order to try and satisfy everyone's requirements (without necessarily
> > reconciling them), I was thinking of introducing a second "Localizable"
> > instance variable in class "MathIllegalArgumentException". This one would
> > not be pattern but a more detailed explanation, that could also be
> > localized.  Hence the class
> >   "NumberOfPointsIsTooSmallException"
> > would inherit from
> >   "NumberIsTooSmallException"
> > and will display
> >   "number of points: argument (0) is less than 2"
> >    ^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >    Specific context       General problem
> 
> Did you not recently suggest to follow the KISS principle ? This is not
> exactly a simple feature and it will completely ruin your previous
> attempt to simplify thing at the exception construction end.

Absolutely not; construction will be as usual:

  throw new NumberOfPointsIsTooSmallException(0, 2);

How much simpler could you expect it to be?

> I really don't understand how this suggestion match you first statement
> of replacing "number of points" with "arguments" because it was too
> complex. [...]

The simple solution is to drop the specific context but you don't want it.
So I'm proposing to add it back. Is it what you want, or are we still
playing ping-pong?

> Now you go to the complete opposite by adding a second message
> to get back the initial level of information, but with a far more
> complex solution.

More complex to implement but not to use (you'll just have to select the
exception class that suits your needs).

> > It will not reduce the global number of enums nor make the number of
> > exceptions small but it will at least have the advantage to separate the
> > general problem from the specific context where it occurred.
> > How does that sound?
> 
> Clumsy.

If that's still your opinion, what alternative do you propose?


Gilles

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: svn commit: r960602 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/analysis/interpolation/ main/java/org/apache/commons/math/exception/ main/java/org/apache/commons/math/util/ main/resources/META-INF/localization/ site/xdoc/ tes...

Posted by Luc Maisonobe <Lu...@free.fr>.
Le 07/07/2010 15:56, Gilles Sadowski a écrit :
>>> And I disagree with both your disagreements. Could you _please_ answer all
>>> the drawbacks of your approach in several scenarios which I've put forward
>>> many times already, instead of always only cling to the one use-case which
>>> you are interested in?
> 
> Still no answer on this...

We are at a dead end here. The examples below were use cases I am
interested in, at least from my point of view. We can probably stop this
discussion here as you don't even acknowledge the efforts we do to find
a consensus.

> 
>>> Please! What kind of ?@#! application is it that you take as an example,
>>> that will print a terse message and exit?  The _least_ a program should
>>> do when it bails out is print the stack trace!
>>
>> I am thinking about the programs I use: space flight dynamics programs
>> that do things like orbit propagation, operational events forecasts
>> (eclipse entry/exit, visibility from ground station, apogee/perigee/node
>> crossings, South Atlantic Anomaly entry/exit, thrusters firings,
>> Sun/Moon/stars visibility/dazzling in optical sensors ...), orbit
>> determination, maneuver optimization, space debris close approaches and
>> avoidance ...
>>
>> These applications are often integrated into a large framework (a
>> satellite control enter). They provide graphical user interface. The
>> errors are often displayed in limited dedicated places (error message
>> line at the bottom of some windows, popup window with one or two text
>> lines, and most of the time a single line of text transmitted to a
>> centralized log application gathering messages from the whole control enter.
>>
>> Another example are web applications. The interactive part runs on a
>> browser and the core engine runs on the server. The messaging protocol
>> between the two doesn't provided anything but a string to display error
>> messages, and the UI is often designed for one line strings, not 50
>> lines stack traces.
>>
>> A third example are applications running on limited mobile devices like
>> phones. The display is very limited, it would not handle a stack trace.
> 
> The problem is not the possible limitation of the interface with the final
> user: an error that originates in CM should not propagate to the final user!

In a perfect world, yes, in practice it *will* occur, so the messages
should not be reduced to too terse one and existing messages should not
be reduced. Many are already too difficult to understand, don't make
this even more difficult.

> For example (selecting at random from the impressive list of applications
> above), if some operator pushes a button named "Debris avoidance" and sees
>  "The number of points is less than 2"
> on his one-line console log. How useful is it?

You are oversimplifying to emphasize your view. The operator has not
only one button (if it were so, a single message would be enough with
something like "failed, bad luck"). Operators do have some parameters to
tune. For example when you adjust an orbit from a number of measurements
and get a number of points less than 2, I guess you would check how many
measurements you consider and if it it not that number that is less than 2.

> 
> I'm talking about precondition violations here.
> If they happen, they must be caught by the application and an appropriate
> error should be generated that is related to the user action that triggered
> the problem.

Of course, but everything is not perfect and preconditions checks are
not always present even where they should.

> This is exactly the confusion I was referring to: Only you, as a veteran CM
> developer, might recognize your "detailed" message string. For a real final
> user it is no more useful than
>   "Argument was less than 2".
> [If CM is really intended to display everything to the top-level, then I
> revise my position, there are far too few error message strings: There
> should be a specific one for each place where an exception is thrown,
> explaining in a detailed message why the error occurred at that place in the
> code... (Just kidding.)]
> Even if it were so, what you'd have achieved is to pinpoint where the
> exception was thrown, without the help of the stack trace. But you are still
> nowhere close to fixing the bug because, without the stack trace, you don't
> know what action really triggered the exception (a bug in CM, or in the
> application, or bad usage from the operator?).
> 
>>> Please! Read chapter 8 of Bloch's Effective Java (less then 20 pages) to see
>>> that indeed the error message must be reported by the user/operator to the
>>> developer. This is not debugging.

Yes, of course, but that is not a reason to reduce error messages.

>>
>> The problem we discuss is not related to Java, it is all about
>> ergonomics. The rules about error messages are consistent everywhere I
>> looked: they should be user oriented, helpful and must not rely on
>> program implementation details. When I read:
>>   "provide user-centered wording in messages (e.g. "there was a problem
>>    in copying the file to your disk" rather than "execution error 159")"
>> in <http://ergo.human.cornell.edu/ahtutorials/interface.html>, I
>> consider it also rules out stack traces.
> 
> Confusion of responsibilities (continued)...
> CM is not an end-user application; it is a low-level component.
> [CM directly communicating with the end-user can also be viewed as breakind
> encapsulation...]

Yes.

> 
>> Of course, Phil you and I can deal with stack traces. In fact, I think
>> all people on this list (a "dev" list) can and do this all the time. But
>> users may not. [...]
> 
> I can agree that stack trace is not for users, though not because it is
> deemed too complicated, but because if the stack trace appears, it often
> means that, somewhere in the development chain, someone has not been careful
> enough.

Yes.

> 
>> You consider our users are developers (I think you wrote
>> it some days ago) and we are not concerned by the users of our users.
>> However, since at the same time you ask for going to unchecked exception
>> which will obviously lead to our messages leaking to the higher level
>> and to final user, I cannot agree with both points at the same time.
> 
> You misunderstood me. I said that the application developer will have the
> choice to recover from unchecked exceptions just the same as with checked
> exceptions. The advantage of unchecked exceptions is that they will relieve
> CM-users who have no way to handle the problem (i.e. choice vs obligation).
> And I also said that _none_ of the CM exceptions should ever reach final
> users (hence my wondering of the necessity of localization inside the CM
> library).

The last two sentences are inconsistent with each other. If CM-users are
relieved from handling the problem because they are not obliged anymore
to do so, then the message will leak up to the user.


> A well-behaved application will want to avoid being crashed by an uncaught
> exception; at some point, it should catch all "RuntimeException"s and signal
> to the user that something went terribly wrong with the current action,
> because an unchecked exception could not be handled. If the programming
> problem is to be solved, the application should log enough information; a
> single line will not do.
> A user who cannot deal with a stack trace should, even more so, never see a
> CM message that relates to a method called many levels down his own action.
> In the same way that his action passes through many layers before calling a
> CM algorithm, then the result (or failure) of this algorithm must be
> conveyed back in a manner that he can relate to.
> 
>> If all messages should be tracked and handled by intermediate code, and
>> if they are only meant to developers with their accompanying stack
>> trace, then they must be checked exception to be sure no error is
>> missed.
> 
> It was probably the Java designer's dream that checked exceptions were the
> ultimate solution to the error handling problem. But their overuse proved
> to be a burden; burden that is dealt with in various ways such as, namely,
>  * exception swallowing, or
>  * every method declared to throw "Exception" (i.e. transferring
>    the burden to the caller) etc.
> 
> Whereas it is so simple not to miss anything:
> 
> public static void main(String[] args) {
>   // ...
> 
>   try {
>     // ...
>   } catch (RuntimeException e) {
>     LOG.error("Oops, unexpected exception (this is a bug): " + e);
>   }
> }

We all agree with that, we want meaningful exceptions (better than the
few ones we have), and we want meaningful messages because we *know*
some of them will leak to the user. It is simply a fact, don't avoid it
by saying its bad programming and should have bee handled beforehand by
preconditions.

> 
>> If we opt for unchecked exception, there will be leaked messages
> 
> Which will just prompt for bug-fixes, consisting in not leaking them
> anymore.

Yes, and this is good and the program will improve with time. But as
long as everything has not been properly fixed, users will be happy to
have good messages.

> 
>> and the stack trace will sometimes not be there (or will be theere for a
>> user than cannot understand or use them). This look to me similar to
>> this wonderful analysis of a web server error message:
>> <http://blog.use-design.com/2008/bad-bad-user/>; [...]
> 
> But that's exactly what you want CM to do: Leaking messages that only
> reflect the inner working of something. As much as this user may not know
> what he did to get a "Cannot handle request", the user of an application
> that just displays the CM exception will feel the same way looking at
>  "Number of points is less than 2".
> I think that you over-estimate the usefulness of the error message string at
> the expense of making it easier for application programmers to catch the
> specific exception that they might want to handle.

I think you over-estimate the importance of making the life of
application programmer easier at the expense of making life of end users
easier. Users are far more important than us.

> 
>> of course from a
>> developer or an experienced user, the message is self explanatory, but
>> consider how it may be misinterpreted by a less experienced user.
> 
> One of my points, again, is that the exception messages are not meant
> to convey a thorough explanation, but to indicate that something went wrong.

There is a difference between thorough information and almost no
information at all (and yes, I am oversimplifying here).

> Another point is that at the level of library component the type of the
> exception object is more important than the String message. Objects make it
> possible to further customize the behaviour of the upper layers of code. The
> String is meant for humans to read, and when that has happened it is too
> late for anything else (the program bailed out).

We agree with that, that's not the point we discuss here. You sold us
the idea of a more complete set of exception with getters and we bought
it. That point is accepted now.

> 
>> To me, the trade-off between our diverging points is to:
>>  1) go to uncheck exceptions wherever possible (your point)
>>  2) reduce number of difference messages (everybody point)
>>  3) keep informational messages (both Phil and mine point)
>>
>> Items 2 and 3 are sometimes in contradiction and should be applied on a
>> message by message basis.
> 
> Please note that I'm not against conveying detailed information. What I've
> been suggesting is a sound and flexible design. IMO that goal implies:
>  1. A set of (stateful) exception classes
>  2. Stringent rules on the use of checked exception
>  3. Encapsulation of messages localization
> 
> Now, one of your requirements is that "getMessage" should display a
> "mini-manual" and, as far as I can see, *that* goal is in contradiction with
> a significant reduction of the message strings.
> Moreover, encapsulation (point 3) will then require a huge set of
> exceptions, most of which will be used only once in the CM code.

This is exactly what I said with item 2 and 3. There is no perfect
solution, we have to find some trade-off and it will not be perfect.

> 
> In order to try and satisfy everyone's requirements (without necessarily
> reconciling them), I was thinking of introducing a second "Localizable"
> instance variable in class "MathIllegalArgumentException". This one would
> not be pattern but a more detailed explanation, that could also be
> localized.  Hence the class
>   "NumberOfPointsIsTooSmallException"
> would inherit from
>   "NumberIsTooSmallException"
> and will display
>   "number of points: argument (0) is less than 2"
>    ^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
>    Specific context       General problem

Did you not recently suggest to follow the KISS principle ? This is not
exactly a simple feature and it will completely ruin your previous
attempt to simplify thing at the exception construction end.

I really don't understand how this suggestion match you first statement
of replacing "number of points" with "arguments" because it was too
complex. Now you go to the complete opposite by adding a second message
to get back the initial level of information, but with a far more
complex solution.

> 
> It will not reduce the global number of enums nor make the number of
> exceptions small but it will at least have the advantage to separate the
> general problem from the specific context where it occurred.
> How does that sound?

Clumsy.


Luc

> 
> 
> Gilles
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: svn commit: r960602 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/analysis/interpolation/ main/java/org/apache/commons/math/exception/ main/java/org/apache/commons/math/util/ main/resources/META-INF/localization/ site/xdoc/ tes...

Posted by Gilles Sadowski <gi...@harfang.homelinux.org>.
> > And I disagree with both your disagreements. Could you _please_ answer all
> > the drawbacks of your approach in several scenarios which I've put forward
> > many times already, instead of always only cling to the one use-case which
> > you are interested in?

Still no answer on this...

> > Please! What kind of ?@#! application is it that you take as an example,
> > that will print a terse message and exit?  The _least_ a program should
> > do when it bails out is print the stack trace!
> 
> I am thinking about the programs I use: space flight dynamics programs
> that do things like orbit propagation, operational events forecasts
> (eclipse entry/exit, visibility from ground station, apogee/perigee/node
> crossings, South Atlantic Anomaly entry/exit, thrusters firings,
> Sun/Moon/stars visibility/dazzling in optical sensors ...), orbit
> determination, maneuver optimization, space debris close approaches and
> avoidance ...
> 
> These applications are often integrated into a large framework (a
> satellite control enter). They provide graphical user interface. The
> errors are often displayed in limited dedicated places (error message
> line at the bottom of some windows, popup window with one or two text
> lines, and most of the time a single line of text transmitted to a
> centralized log application gathering messages from the whole control enter.
> 
> Another example are web applications. The interactive part runs on a
> browser and the core engine runs on the server. The messaging protocol
> between the two doesn't provided anything but a string to display error
> messages, and the UI is often designed for one line strings, not 50
> lines stack traces.
> 
> A third example are applications running on limited mobile devices like
> phones. The display is very limited, it would not handle a stack trace.

The problem is not the possible limitation of the interface with the final
user: an error that originates in CM should not propagate to the final user!
For example (selecting at random from the impressive list of applications
above), if some operator pushes a button named "Debris avoidance" and sees
 "The number of points is less than 2"
on his one-line console log. How useful is it?

I'm talking about precondition violations here.
If they happen, they must be caught by the application and an appropriate
error should be generated that is related to the user action that triggered
the problem.
This is exactly the confusion I was referring to: Only you, as a veteran CM
developer, might recognize your "detailed" message string. For a real final
user it is no more useful than
  "Argument was less than 2".
[If CM is really intended to display everything to the top-level, then I
revise my position, there are far too few error message strings: There
should be a specific one for each place where an exception is thrown,
explaining in a detailed message why the error occurred at that place in the
code... (Just kidding.)]
Even if it were so, what you'd have achieved is to pinpoint where the
exception was thrown, without the help of the stack trace. But you are still
nowhere close to fixing the bug because, without the stack trace, you don't
know what action really triggered the exception (a bug in CM, or in the
application, or bad usage from the operator?).

> > Please! Read chapter 8 of Bloch's Effective Java (less then 20 pages) to see
> > that indeed the error message must be reported by the user/operator to the
> > developer. This is not debugging.
> 
> The problem we discuss is not related to Java, it is all about
> ergonomics. The rules about error messages are consistent everywhere I
> looked: they should be user oriented, helpful and must not rely on
> program implementation details. When I read:
>   "provide user-centered wording in messages (e.g. "there was a problem
>    in copying the file to your disk" rather than "execution error 159")"
> in <http://ergo.human.cornell.edu/ahtutorials/interface.html>, I
> consider it also rules out stack traces.

Confusion of responsibilities (continued)...
CM is not an end-user application; it is a low-level component.
[CM directly communicating with the end-user can also be viewed as breakind
encapsulation...]

> Of course, Phil you and I can deal with stack traces. In fact, I think
> all people on this list (a "dev" list) can and do this all the time. But
> users may not. [...]

I can agree that stack trace is not for users, though not because it is
deemed too complicated, but because if the stack trace appears, it often
means that, somewhere in the development chain, someone has not been careful
enough.

> You consider our users are developers (I think you wrote
> it some days ago) and we are not concerned by the users of our users.
> However, since at the same time you ask for going to unchecked exception
> which will obviously lead to our messages leaking to the higher level
> and to final user, I cannot agree with both points at the same time.

You misunderstood me. I said that the application developer will have the
choice to recover from unchecked exceptions just the same as with checked
exceptions. The advantage of unchecked exceptions is that they will relieve
CM-users who have no way to handle the problem (i.e. choice vs obligation).
And I also said that _none_ of the CM exceptions should ever reach final
users (hence my wondering of the necessity of localization inside the CM
library).
A well-behaved application will want to avoid being crashed by an uncaught
exception; at some point, it should catch all "RuntimeException"s and signal
to the user that something went terribly wrong with the current action,
because an unchecked exception could not be handled. If the programming
problem is to be solved, the application should log enough information; a
single line will not do.
A user who cannot deal with a stack trace should, even more so, never see a
CM message that relates to a method called many levels down his own action.
In the same way that his action passes through many layers before calling a
CM algorithm, then the result (or failure) of this algorithm must be
conveyed back in a manner that he can relate to.

> If all messages should be tracked and handled by intermediate code, and
> if they are only meant to developers with their accompanying stack
> trace, then they must be checked exception to be sure no error is
> missed.

It was probably the Java designer's dream that checked exceptions were the
ultimate solution to the error handling problem. But their overuse proved
to be a burden; burden that is dealt with in various ways such as, namely,
 * exception swallowing, or
 * every method declared to throw "Exception" (i.e. transferring
   the burden to the caller) etc.

Whereas it is so simple not to miss anything:

public static void main(String[] args) {
  // ...

  try {
    // ...
  } catch (RuntimeException e) {
    LOG.error("Oops, unexpected exception (this is a bug): " + e);
  }
}

> If we opt for unchecked exception, there will be leaked messages

Which will just prompt for bug-fixes, consisting in not leaking them
anymore.

> and the stack trace will sometimes not be there (or will be theere for a
> user than cannot understand or use them). This look to me similar to
> this wonderful analysis of a web server error message:
> <http://blog.use-design.com/2008/bad-bad-user/>; [...]

But that's exactly what you want CM to do: Leaking messages that only
reflect the inner working of something. As much as this user may not know
what he did to get a "Cannot handle request", the user of an application
that just displays the CM exception will feel the same way looking at
 "Number of points is less than 2".
I think that you over-estimate the usefulness of the error message string at
the expense of making it easier for application programmers to catch the
specific exception that they might want to handle.

> of course from a
> developer or an experienced user, the message is self explanatory, but
> consider how it may be misinterpreted by a less experienced user.

One of my points, again, is that the exception messages are not meant
to convey a thorough explanation, but to indicate that something went wrong.
Another point is that at the level of library component the type of the
exception object is more important than the String message. Objects make it
possible to further customize the behaviour of the upper layers of code. The
String is meant for humans to read, and when that has happened it is too
late for anything else (the program bailed out).

> To me, the trade-off between our diverging points is to:
>  1) go to uncheck exceptions wherever possible (your point)
>  2) reduce number of difference messages (everybody point)
>  3) keep informational messages (both Phil and mine point)
> 
> Items 2 and 3 are sometimes in contradiction and should be applied on a
> message by message basis.

Please note that I'm not against conveying detailed information. What I've
been suggesting is a sound and flexible design. IMO that goal implies:
 1. A set of (stateful) exception classes
 2. Stringent rules on the use of checked exception
 3. Encapsulation of messages localization

Now, one of your requirements is that "getMessage" should display a
"mini-manual" and, as far as I can see, *that* goal is in contradiction with
a significant reduction of the message strings.
Moreover, encapsulation (point 3) will then require a huge set of
exceptions, most of which will be used only once in the CM code.

In order to try and satisfy everyone's requirements (without necessarily
reconciling them), I was thinking of introducing a second "Localizable"
instance variable in class "MathIllegalArgumentException". This one would
not be pattern but a more detailed explanation, that could also be
localized.  Hence the class
  "NumberOfPointsIsTooSmallException"
would inherit from
  "NumberIsTooSmallException"
and will display
  "number of points: argument (0) is less than 2"
   ^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   Specific context       General problem

It will not reduce the global number of enums nor make the number of
exceptions small but it will at least have the advantage to separate the
general problem from the specific context where it occurred.
How does that sound?


Gilles

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: svn commit: r960602 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/analysis/interpolation/ main/java/org/apache/commons/math/exception/ main/java/org/apache/commons/math/util/ main/resources/META-INF/localization/ site/xdoc/ tes...

Posted by Luc Maisonobe <Lu...@free.fr>.
Le 06/07/2010 11:20, Gilles Sadowski a écrit :
>>>> The stack trace certainly will show where the bad thing happened.
>>>> Nothing important is lost: What went wrong is as clearly identified by
>>>> saying
>>>>  "The argument must be >= 2"
>>>> as by saying
>>>>  "The number of points must be >= 2"
>>>> The problem is that the caller passed a wrong argument and this is a bug and
>>>> no amount of detailed message will be a substitute for reading the
>>>> documentation and source code and make the correct call.
>>>
>>> Sorry, but I disagree here.  There is definitely loss of information
>>> in the stack trace. I would prefer to retain the detailed error
>>
>> I also disagree with Gilles, but not the same reason. Some people will
>> not have access to the stack trace. It is even more important for
>> unchecked exception since they may not be intercepted by high level
>> applications. All they will get is a terse message print on a log file
>> or a popup window before the application stops.
>>
>> Users are not here to debug the code for developers.
>>
>> Also the Apache license allows people to reuse our code in proprietary
>> environment with closed source. For sure in this case, no stack trace
>> will be available.
>>
>> Luc
> 
> And I disagree with both your disagreements. Could you _please_ answer all
> the drawbacks of your approach in several scenarios which I've put forward
> many times already, instead of always only cling to the one use-case which
> you are interested in?
> 
> Please! What kind of ?@#! application is it that you take as an example,
> that will print a terse message and exit?  The _least_ a program should
> do when it bails out is print the stack trace!

I am thinking about the programs I use: space flight dynamics programs
that do things like orbit propagation, operational events forecasts
(eclipse entry/exit, visibility from ground station, apogee/perigee/node
crossings, South Atlantic Anomaly entry/exit, thrusters firings,
Sun/Moon/stars visibility/dazzling in optical sensors ...), orbit
determination, maneuver optimization, space debris close approaches and
avoidance ...

These applications are often integrated into a large framework (a
satellite control enter). They provide graphical user interface. The
errors are often displayed in limited dedicated places (error message
line at the bottom of some windows, popup window with one or two text
lines, and most of the time a single line of text transmitted to a
centralized log application gathering messages from the whole control enter.

Another example are web applications. The interactive part runs on a
browser and the core engine runs on the server. The messaging protocol
between the two doesn't provided anything but a string to display error
messages, and the UI is often designed for one line strings, not 50
lines stack traces.

A third example are applications running on limited mobile devices like
phones. The display is very limited, it would not handle a stack trace.


> 
> Please! Read chapter 8 of Bloch's Effective Java (less then 20 pages) to see
> that indeed the error message must be reported by the user/operator to the
> developer. This is not debugging.

The problem we discuss is not related to Java, it is all about
ergonomics. The rules about error messages are consistent everywhere I
looked: they should be user oriented, helpful and must not rely on
program implementation details. When I read:
  "provide user-centered wording in messages (e.g. "there was a problem
   in copying the file to your disk" rather than "execution error 159")"
in <http://ergo.human.cornell.edu/ahtutorials/interface.html>, I
consider it also rules out stack traces.

Of course, Phil you and I can deal with stack traces. In fact, I think
all people on this list (a "dev" list) can and do this all the time. But
users may not. You consider our users are developers (I think you wrote
it some days ago) and we are not concerned by the users of our users.
However, since at the same time you ask for going to unchecked exception
which will obviously lead to our messages leaking to the higher level
and to final user, I cannot agree with both points at the same time.

If all messages should be tracked and handled by intermediate code, and
if they are only meant to developers with their accompanying stack
trace, then they must be checked exception to be sure no error is
missed. If we opt for unchecked exception, there will be leaked messages
and the stack trace will sometimes not be there (or will be theere for a
user than cannot understand or use them). This look to me similar to
this wonderful analysis of a web server error message:
<http://blog.use-design.com/2008/bad-bad-user/>; of course from a
developer or an experienced user, the message is self explanatory, but
consider how it may be misinterpreted by a less experienced user.

To me, the trade-off between our diverging points is to:
 1) go to uncheck exceptions wherever possible (your point)
 2) reduce number of difference messages (everybody point)
 3) keep informational messages (both Phil and mine point)

Items 2 and 3 are sometimes in contradiction and should be applied on a
message by message basis.

Luc

> 
>>> message that tells what quantity was "too small."  And I do not
>>> really see the value in the "NumberTooSmallException" altogether,
>>> frankly.  By substituting an exception that does not identify what
>>> quantity was "too small" for an IllegalArgumeentException with a
>>> message giving the full context, what exactly have we achieved?
> 
> Then perhaps you missed some of the comments here above, and also at
>   https://issues.apache.org/jira/browse/MATH-195
> and/or at
>   https://issues.apache.org/jira/browse/MATH-361
> and references therein (Bloch, Goetz).
> 
> Or perhaps we (Eckel et al.) are all wrong. In this case, please show me
> modern, high-profile, Java library projects that deal with exceptions in
> the same way that you want it for CM.
> 
> 
> Gilles
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: svn commit: r960602 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/analysis/interpolation/ main/java/org/apache/commons/math/exception/ main/java/org/apache/commons/math/util/ main/resources/META-INF/localization/ site/xdoc/ tes...

Posted by Gilles Sadowski <gi...@harfang.homelinux.org>.
> > Then perhaps you missed some of the comments here above, and also at
> >   https://issues.apache.org/jira/browse/MATH-195
> > and/or at
> >   https://issues.apache.org/jira/browse/MATH-361
> > and references therein (Bloch, Goetz).
> > 
> > Or perhaps we (Eckel et al.) are all wrong. In this case, please show me
> > modern, high-profile, Java library projects that deal with exceptions in
> > the same way that you want it for CM.
> > 
> 
> What is important and relevant to discussion here is how we
> structure and manage exceptions in [math].  It is best for us to
> keep the discussion focused on concrete examples, with arguments
> supported directly using [math] use cases.

I'm proposing a revision of the exception design structure (or lack thereof)
that is supported by those references, and you say that they are not
relevant. I cannot argue with that.

>  Luc and I have provided
> examples of use cases where the changes that you are proposing are
> not optimal for users.  You need to respond directly to these examples.

You have a number of use cases equal to 1. Of course, the current design
makes it impossible to implement the use cases which I presented (cf. the
initial mail about "Localization and error handling", the comments on JIRA,
and on this ML). Because of this you could say that I have 0 use case; so...
You win :-!

> The specific change that we are talking about here is the
> replacement of an IllegalArgumentException with an error message
> containing context information about what argument was "illegal" and
> why by a "NumberTooLargeException" containing no reference to the
> argument.  I have two problems with this change:
> 
> 1. There is loss of failure-capture information (i.e., the specific
> argument that was out of range)
> 2. I don't see the value in this abstraction.  We all agree that we
> need to add more structure to our exceptions hierarchy.  I may well
> be missing something here, but I don't see what this particular
> abstraction buys us and in particular why it is the appropriate
> abstraction for the context in which it is thrown above.
> 
> Can you respond directly to these issues, please?

Strictly speaking you are right, replacing "number of points" by "argument"
looses information. However, I think that a user with only the error message
created by CM will be as lost with your message as with mine. My point is
that a precondition violation message is almost always useless if there is
no stack trace to recover the root of the problem. Your order of importance
of information bits is definitely not the same as mine.
[But see at the end of my other reply to this thread, where I try to address
your concerns, while you still didn't address mine.]


Gilles

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: svn commit: r960602 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/analysis/interpolation/ main/java/org/apache/commons/math/exception/ main/java/org/apache/commons/math/util/ main/resources/META-INF/localization/ site/xdoc/ tes...

Posted by Phil Steitz <ph...@gmail.com>.
Gilles Sadowski wrote:
>>>> The stack trace certainly will show where the bad thing happened.
>>>> Nothing important is lost: What went wrong is as clearly identified by
>>>> saying
>>>>  "The argument must be >= 2"
>>>> as by saying
>>>>  "The number of points must be >= 2"
>>>> The problem is that the caller passed a wrong argument and this is a bug and
>>>> no amount of detailed message will be a substitute for reading the
>>>> documentation and source code and make the correct call.
>>> Sorry, but I disagree here.  There is definitely loss of information
>>> in the stack trace. I would prefer to retain the detailed error
>> I also disagree with Gilles, but not the same reason. Some people will
>> not have access to the stack trace. It is even more important for
>> unchecked exception since they may not be intercepted by high level
>> applications. All they will get is a terse message print on a log file
>> or a popup window before the application stops.
>>
>> Users are not here to debug the code for developers.
>>
>> Also the Apache license allows people to reuse our code in proprietary
>> environment with closed source. For sure in this case, no stack trace
>> will be available.
>>
>> Luc
> 
> And I disagree with both your disagreements. Could you _please_ answer all
> the drawbacks of your approach in several scenarios which I've put forward
> many times already, instead of always only cling to the one use-case which
> you are interested in?
> 
> Please! What kind of ?@#! application is it that you take as an example,
> that will print a terse message and exit?  The _least_ a program should
> do when it bails out is print the stack trace!
> 
> Please! Read chapter 8 of Bloch's Effective Java (less then 20 pages) to see
> that indeed the error message must be reported by the user/operator to the
> developer. This is not debugging.
> 
>>> message that tells what quantity was "too small."  And I do not
>>> really see the value in the "NumberTooSmallException" altogether,
>>> frankly.  By substituting an exception that does not identify what
>>> quantity was "too small" for an IllegalArgumeentException with a
>>> message giving the full context, what exactly have we achieved?
> 
> Then perhaps you missed some of the comments here above, and also at
>   https://issues.apache.org/jira/browse/MATH-195
> and/or at
>   https://issues.apache.org/jira/browse/MATH-361
> and references therein (Bloch, Goetz).
> 
> Or perhaps we (Eckel et al.) are all wrong. In this case, please show me
> modern, high-profile, Java library projects that deal with exceptions in
> the same way that you want it for CM.
> 

What is important and relevant to discussion here is how we
structure and manage exceptions in [math].  It is best for us to
keep the discussion focused on concrete examples, with arguments
supported directly using [math] use cases.  Luc and I have provided
examples of use cases where the changes that you are proposing are
not optimal for users.  You need to respond directly to these examples.

The specific change that we are talking about here is the
replacement of an IllegalArgumentException with an error message
containing context information about what argument was "illegal" and
why by a "NumberTooLargeException" containing no reference to the
argument.  I have two problems with this change:

1. There is loss of failure-capture information (i.e., the specific
argument that was out of range)
2. I don't see the value in this abstraction.  We all agree that we
need to add more structure to our exceptions hierarchy.  I may well
be missing something here, but I don't see what this particular
abstraction buys us and in particular why it is the appropriate
abstraction for the context in which it is thrown above.

Can you respond directly to these issues, please?

Phil


> 
> Gilles
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: svn commit: r960602 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/analysis/interpolation/ main/java/org/apache/commons/math/exception/ main/java/org/apache/commons/math/util/ main/resources/META-INF/localization/ site/xdoc/ tes...

Posted by Gilles Sadowski <gi...@harfang.homelinux.org>.
> >> The stack trace certainly will show where the bad thing happened.
> >> Nothing important is lost: What went wrong is as clearly identified by
> >> saying
> >>  "The argument must be >= 2"
> >> as by saying
> >>  "The number of points must be >= 2"
> >> The problem is that the caller passed a wrong argument and this is a bug and
> >> no amount of detailed message will be a substitute for reading the
> >> documentation and source code and make the correct call.
> > 
> > Sorry, but I disagree here.  There is definitely loss of information
> > in the stack trace. I would prefer to retain the detailed error
> 
> I also disagree with Gilles, but not the same reason. Some people will
> not have access to the stack trace. It is even more important for
> unchecked exception since they may not be intercepted by high level
> applications. All they will get is a terse message print on a log file
> or a popup window before the application stops.
> 
> Users are not here to debug the code for developers.
> 
> Also the Apache license allows people to reuse our code in proprietary
> environment with closed source. For sure in this case, no stack trace
> will be available.
> 
> Luc

And I disagree with both your disagreements. Could you _please_ answer all
the drawbacks of your approach in several scenarios which I've put forward
many times already, instead of always only cling to the one use-case which
you are interested in?

Please! What kind of ?@#! application is it that you take as an example,
that will print a terse message and exit?  The _least_ a program should
do when it bails out is print the stack trace!

Please! Read chapter 8 of Bloch's Effective Java (less then 20 pages) to see
that indeed the error message must be reported by the user/operator to the
developer. This is not debugging.

> > message that tells what quantity was "too small."  And I do not
> > really see the value in the "NumberTooSmallException" altogether,
> > frankly.  By substituting an exception that does not identify what
> > quantity was "too small" for an IllegalArgumeentException with a
> > message giving the full context, what exactly have we achieved?

Then perhaps you missed some of the comments here above, and also at
  https://issues.apache.org/jira/browse/MATH-195
and/or at
  https://issues.apache.org/jira/browse/MATH-361
and references therein (Bloch, Goetz).

Or perhaps we (Eckel et al.) are all wrong. In this case, please show me
modern, high-profile, Java library projects that deal with exceptions in
the same way that you want it for CM.


Gilles

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: svn commit: r960602 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/analysis/interpolation/ main/java/org/apache/commons/math/exception/ main/java/org/apache/commons/math/util/ main/resources/META-INF/localization/ site/xdoc/ tes...

Posted by Luc Maisonobe <Lu...@free.fr>.
Le 06/07/2010 02:55, Phil Steitz a écrit :
> Gilles Sadowski wrote:
>>>> MATH-361
>>>> MATH-382
>>> In the future, please separate commits if possible for separate
>>> issues.  In this case, a bug was fixed and some exception
>>> refactoring was also introduced.  These should be separate commits
>>
>> I know, and I do it whenever possible but I found out about the bug
>> (MATH-382) when I had already updated the file (MATH-361) and did not have
>> time to spend rolling back the changes for something that trivial.
> 
> As I said, please separate commits in the future.  It is not that
> difficult to svn revert and manage source so your local mods for
> different issues can be separated.  Commit logs and diffs get
> attached to issues and it makes it easier to tell what has happened
> if we separate commits for different issues.
> 
>>
>>> and changes.xml should be updated with entries for each.
>>
>> There is already an entry about issue 361.
>> Do you really want that I duplicate that entry each time I work a little on
>> this issue?
> 
> What I tend to do is create an entry in changes.xml for an issue in
> progress and update it to reflect the changes associated with the
> issue.  We use changes.xml as the source for the release notes, so
> it should include references to all new classes, refactoring or
> other significant changes to to the code.
>>
>>> It would be great to discuss the exception refactoring some more.
>>> The commit below gives some concrete examples.  I would like to
>>> understand better why "NumberIsTooLargeException" and
>>> "NumberIsTooSmallException" are better abstractions than more
>>> domain-specific ones.
>>
>> Of course we could have an exception package as big as the current list of
>> enums:
>>   NumberOfFooIsTooSmallException
>>   NumberOfBarIsTooSmallException
>>   etc.
>>
>> However, my opinion is that an exception is supposed to tell what went
>> wrong, not why. It simply cannot be a user's manual!
>>
>>> Also, are we not losing information in stack
>>> traces when we do:
>>>
>>>>          if (x.length < 2) {
>>>> -            throw
>>> MathRuntimeException.createIllegalArgumentException(
>>>> -                  LocalizedFormats.WRONG_NUMBER_OF_POINTS, 2,
>>> x.length);
>>>> +            throw new NumberIsTooSmallException(x.length, 2, true);
>>> Perhaps another parameter identifying the quantity that is "too
>>> large" is needed?
>>
>> The stack trace certainly will show where the bad thing happened.
>> Nothing important is lost: What went wrong is as clearly identified by
>> saying
>>  "The argument must be >= 2"
>> as by saying
>>  "The number of points must be >= 2"
>> The problem is that the caller passed a wrong argument and this is a bug and
>> no amount of detailed message will be a substitute for reading the
>> documentation and source code and make the correct call.
> 
> Sorry, but I disagree here.  There is definitely loss of information
> in the stack trace. I would prefer to retain the detailed error

I also disagree with Gilles, but not the same reason. Some people will
not have access to the stack trace. It is even more important for
unchecked exception since they may not be intercepted by high level
applications. All they will get is a terse message print on a log file
or a popup window before the application stops.

Users are not here to debug the code for developers.

Also the Apache license allows people to reuse our code in proprietary
environment with closed source. For sure in this case, no stack trace
will be available.

Luc

> message that tells what quantity was "too small."  And I do not
> really see the value in the "NumberTooSmallException" altogether,
> frankly.  By substituting an exception that does not identify what
> quantity was "too small" for an IllegalArgumeentException with a
> message giving the full context, what exactly have we achieved?
> 
> Phil
>>
>> Exceptions enhance the robustness of the library; they cannot premptively
>> prevent bad usage...
>>
>>
>> Best regards,
>> Gilles
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>>
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: svn commit: r960602 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/analysis/interpolation/ main/java/org/apache/commons/math/exception/ main/java/org/apache/commons/math/util/ main/resources/META-INF/localization/ site/xdoc/ tes...

Posted by Phil Steitz <ph...@gmail.com>.
Gilles Sadowski wrote:
>>> MATH-361
>>> MATH-382
>> In the future, please separate commits if possible for separate
>> issues.  In this case, a bug was fixed and some exception
>> refactoring was also introduced.  These should be separate commits
> 
> I know, and I do it whenever possible but I found out about the bug
> (MATH-382) when I had already updated the file (MATH-361) and did not have
> time to spend rolling back the changes for something that trivial.

As I said, please separate commits in the future.  It is not that
difficult to svn revert and manage source so your local mods for
different issues can be separated.  Commit logs and diffs get
attached to issues and it makes it easier to tell what has happened
if we separate commits for different issues.

> 
>> and changes.xml should be updated with entries for each.
> 
> There is already an entry about issue 361.
> Do you really want that I duplicate that entry each time I work a little on
> this issue?

What I tend to do is create an entry in changes.xml for an issue in
progress and update it to reflect the changes associated with the
issue.  We use changes.xml as the source for the release notes, so
it should include references to all new classes, refactoring or
other significant changes to to the code.
> 
>> It would be great to discuss the exception refactoring some more.
>> The commit below gives some concrete examples.  I would like to
>> understand better why "NumberIsTooLargeException" and
>> "NumberIsTooSmallException" are better abstractions than more
>> domain-specific ones.
> 
> Of course we could have an exception package as big as the current list of
> enums:
>   NumberOfFooIsTooSmallException
>   NumberOfBarIsTooSmallException
>   etc.
> 
> However, my opinion is that an exception is supposed to tell what went
> wrong, not why. It simply cannot be a user's manual!
> 
>> Also, are we not losing information in stack
>> traces when we do:
>>
>>>          if (x.length < 2) {
>>> -            throw
>> MathRuntimeException.createIllegalArgumentException(
>>> -                  LocalizedFormats.WRONG_NUMBER_OF_POINTS, 2,
>> x.length);
>>> +            throw new NumberIsTooSmallException(x.length, 2, true);
>> Perhaps another parameter identifying the quantity that is "too
>> large" is needed?
> 
> The stack trace certainly will show where the bad thing happened.
> Nothing important is lost: What went wrong is as clearly identified by
> saying
>  "The argument must be >= 2"
> as by saying
>  "The number of points must be >= 2"
> The problem is that the caller passed a wrong argument and this is a bug and
> no amount of detailed message will be a substitute for reading the
> documentation and source code and make the correct call.

Sorry, but I disagree here.  There is definitely loss of information
in the stack trace. I would prefer to retain the detailed error
message that tells what quantity was "too small."  And I do not
really see the value in the "NumberTooSmallException" altogether,
frankly.  By substituting an exception that does not identify what
quantity was "too small" for an IllegalArgumeentException with a
message giving the full context, what exactly have we achieved?

Phil
> 
> Exceptions enhance the robustness of the library; they cannot premptively
> prevent bad usage...
> 
> 
> Best regards,
> Gilles
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: svn commit: r960602 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/analysis/interpolation/ main/java/org/apache/commons/math/exception/ main/java/org/apache/commons/math/util/ main/resources/META-INF/localization/ site/xdoc/ tes...

Posted by Gilles Sadowski <gi...@harfang.homelinux.org>.
> > MATH-361
> > MATH-382
> 
> In the future, please separate commits if possible for separate
> issues.  In this case, a bug was fixed and some exception
> refactoring was also introduced.  These should be separate commits

I know, and I do it whenever possible but I found out about the bug
(MATH-382) when I had already updated the file (MATH-361) and did not have
time to spend rolling back the changes for something that trivial.

> and changes.xml should be updated with entries for each.

There is already an entry about issue 361.
Do you really want that I duplicate that entry each time I work a little on
this issue?

> It would be great to discuss the exception refactoring some more.
> The commit below gives some concrete examples.  I would like to
> understand better why "NumberIsTooLargeException" and
> "NumberIsTooSmallException" are better abstractions than more
> domain-specific ones.

Of course we could have an exception package as big as the current list of
enums:
  NumberOfFooIsTooSmallException
  NumberOfBarIsTooSmallException
  etc.

However, my opinion is that an exception is supposed to tell what went
wrong, not why. It simply cannot be a user's manual!

> Also, are we not losing information in stack
> traces when we do:
> 
> >          if (x.length < 2) {
> > -            throw
> MathRuntimeException.createIllegalArgumentException(
> > -                  LocalizedFormats.WRONG_NUMBER_OF_POINTS, 2,
> x.length);
> > +            throw new NumberIsTooSmallException(x.length, 2, true);
> 
> Perhaps another parameter identifying the quantity that is "too
> large" is needed?

The stack trace certainly will show where the bad thing happened.
Nothing important is lost: What went wrong is as clearly identified by
saying
 "The argument must be >= 2"
as by saying
 "The number of points must be >= 2"
The problem is that the caller passed a wrong argument and this is a bug and
no amount of detailed message will be a substitute for reading the
documentation and source code and make the correct call.

Exceptions enhance the robustness of the library; they cannot premptively
prevent bad usage...


Best regards,
Gilles

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org