new Value interface

This commit is contained in:
Denis Molony 2016-03-16 17:15:39 +11:00
parent 49c66918e1
commit b87609c9d0
22 changed files with 266 additions and 267 deletions

View File

@ -2,33 +2,14 @@ package com.bytezone.diskbrowser.visicalc;
public class Abs extends Function
{
private boolean hasChecked;
private double value = 0;
Abs (Sheet parent, String text)
{
super (parent, text);
}
@Override
public boolean hasValue ()
public void calculate ()
{
if (!hasChecked)
calculate ();
return hasValue;
}
@Override
public double getValue ()
{
return hasValue () ? value : 0;
}
private void calculate ()
{
hasChecked = true;
hasValue = true;
Expression exp = new Expression (parent, functionText);
value = Math.abs (exp.getValue ());
}

View File

@ -9,8 +9,8 @@ class And extends Function
}
@Override
public double getValue ()
public void calculate ()
{
return 0;
value = 0;
}
}

View File

@ -28,6 +28,7 @@ class Cell implements Comparable<Cell>, Value
{
this.parent = parent;
this.address = address;
type = CellType.VALUE; // default to VALUE, formatting may change it
}
public boolean isValue ()
@ -110,8 +111,8 @@ class Cell implements Comparable<Cell>, Value
String getText (int colWidth, char defaultFormat)
{
// cell may have been created when formatted but no type set
if (type == null)
return justify ("", colWidth);
// if (type == null)
// return justify ("", colWidth);
switch (type)
{
@ -122,22 +123,21 @@ class Cell implements Comparable<Cell>, Value
return justify (repeat, colWidth);
case VALUE:
if (hasValue ())
{
Double value = getValue ();
if (Double.isNaN (value))
return justify ("", colWidth);
if (value.isError () || value.isNaN ())
return justify (value.getText (), colWidth);
Double thisValue = value.getValue ();
char format = cellFormat != ' ' ? cellFormat : defaultFormat;
if (format == 'I')
{
String integerFormat = String.format ("%%%d.0f", colWidth);
return String.format (integerFormat, value);
return String.format (integerFormat, thisValue);
}
else if (format == '$')
{
String currencyFormat = String.format ("%%%d.%ds", colWidth, colWidth);
return String.format (currencyFormat, nf.format (value));
return String.format (currencyFormat, nf.format (thisValue));
}
else if (format == '*')
{
@ -149,7 +149,7 @@ class Cell implements Comparable<Cell>, Value
{
// this could be improved
String numberFormat = String.format ("%%%d.3f", colWidth + 4);
String val = String.format (numberFormat, value);
String val = String.format (numberFormat, thisValue);
while (val.endsWith ("0"))
val = ' ' + val.substring (0, val.length () - 1);
if (val.endsWith ("."))
@ -159,10 +159,7 @@ class Cell implements Comparable<Cell>, Value
return val;
}
}
// else
// return justify ("", colWidth);
}
return getError ();
return getText ();
}
private String justify (String text, int colWidth)
@ -177,40 +174,48 @@ class Cell implements Comparable<Cell>, Value
return (String.format (labelFormat, text));
}
@Override
public boolean hasValue ()
{
if (type == CellType.VALUE)
return value.hasValue ();
return false;
}
// this should be called when doing calculations
@Override
public double getValue ()
{
if (type != CellType.VALUE)
return 0;
assert type == CellType.VALUE;
return value.getValue ();
}
@Override
public String getError ()
public String getText ()
{
return value.getError ();
assert type == CellType.VALUE;
return value.getText ();
}
void calculate ()
@Override
public boolean isError ()
{
assert type == CellType.VALUE;
return value.isError ();
}
@Override
public boolean isNaN ()
{
assert type == CellType.VALUE;
return value.isNaN ();
}
@Override
public void calculate ()
{
assert type == CellType.VALUE;
if (expressionText == null)
{
System.out.printf ("%s null expression text %n", address);
value = Function.getInstance (parent, "@ERROR()");
value = Function.getInstance (parent, "@ERROR");
}
else
// could use Number or Cell for simple Values
// should use Number or Cell for simple Values
value = new Expression (parent, expressionText);
value.calculate ();
}
@Override

View File

@ -3,8 +3,6 @@ package com.bytezone.diskbrowser.visicalc;
class Count extends Function
{
private final Range range;
private boolean hasChecked;
private double count = 0;
public Count (Sheet parent, String text)
{
@ -13,33 +11,20 @@ class Count extends Function
}
@Override
public boolean hasValue ()
public void calculate ()
{
if (!hasChecked)
calculate ();
return hasValue;
}
@Override
public double getValue ()
{
return hasValue () ? count : 0;
}
private void calculate ()
{
hasChecked = true;
hasValue = false;
value = 0;
for (Address address : range)
{
Cell cell = parent.getCell (address);
if (cell != null && cell.hasValue ())
if (cell == null || cell.isError () || cell.isNaN ())
{
hasValue = true;
if (cell.getValue () != 0.0)
count++;
isError = true;
break;
}
if (cell.getValue () != 0.0)
value++;
}
}
}

View File

@ -8,15 +8,15 @@ class Error extends Function
}
@Override
public boolean hasValue ()
public boolean isError ()
{
return false;
return true;
}
@Override
public String getError ()
public boolean isNaN ()
{
return "@Error";
return true;
}
@Override
@ -24,4 +24,9 @@ class Error extends Function
{
return 0;
}
@Override
public void calculate ()
{
}
}

View File

@ -32,7 +32,8 @@ class Expression implements Value
private final List<String> operators = new ArrayList<String> ();
private final List<String> signs = new ArrayList<String> ();
private boolean hasValue;
protected boolean isError;
private double value;
public Expression (Sheet parent, String text)
{
@ -112,14 +113,13 @@ class Expression implements Value
}
assert values.size () > 0;
hasValue = true;
}
@Override
public double getValue ()
public void calculate ()
{
Value thisValue = values.get (0);
double value = thisValue == null ? 0 : values.get (0).getValue ();
value = thisValue == null ? 0 : values.get (0).getValue ();
String sign = signs.get (0);
if (sign.equals ("(-)"))
@ -146,21 +146,36 @@ class Expression implements Value
else if (operator.equals ("^"))
value = Math.pow (value, nextValue);
}
}
@Override
public boolean isNaN ()
{
return Double.isNaN (value);
}
@Override
public String getText ()
{
if (isNaN ())
return "NaN";
if (isError ())
return "Error";
return "";
}
@Override
public boolean isError ()
{
return isError;
}
@Override
public double getValue ()
{
return value;
}
@Override
public boolean hasValue ()
{
return hasValue;
}
@Override
public String getError ()
{
return hasValue ? "" : "Error";
}
private String checkBrackets (String input)
{
String line = input.trim ();

View File

@ -32,7 +32,9 @@ abstract class Function implements Value
protected final Sheet parent;
protected String functionText;
protected boolean hasValue;
protected boolean isError;
protected double value;
static Function getInstance (Sheet parent, String text)
{
@ -95,19 +97,37 @@ abstract class Function implements Value
// get function's parameter string
int pos = text.indexOf ('(');
if (pos >= 0)
this.functionText = text.substring (pos + 1, text.length () - 1);
functionText = text.substring (pos + 1, text.length () - 1);
else
functionText = "";
}
@Override
public boolean hasValue ()
public boolean isError ()
{
return hasValue;
return isError;
}
@Override
public String getError ()
public boolean isNaN ()
{
return hasValue ? "" : "Error";
return Double.isNaN (value);
}
@Override
public double getValue ()
{
return value;
}
@Override
public String getText ()
{
if (isNaN ())
return "NaN";
if (isError ())
return "Error";
return "";
}
protected Range getRange (String text)

View File

@ -15,25 +15,27 @@ class If extends Function
int pos1 = functionText.indexOf (',');
int pos2 = functionText.indexOf (',', pos1 + 1);
condition = new Condition (parent, functionText.substring (0, pos1));
textTrue = functionText.substring (pos1 + 1, pos2);
textFalse = functionText.substring (pos2 + 1);
}
@Override
public double getValue ()
public void calculate ()
{
if (condition.getResult ())
{
if (expTrue == null)
expTrue = new Expression (parent, textTrue);
return expTrue.getValue ();
value = expTrue.getValue ();
}
else
{
if (expFalse == null)
expFalse = new Expression (parent, textFalse);
return expFalse.getValue ();
value = expFalse.getValue ();
}
}

View File

@ -9,8 +9,9 @@ public class Int extends Function
}
@Override
public double getValue ()
public void calculate ()
{
return 0;
Expression exp = new Expression (parent, functionText);
value = (int) exp.getValue ();
}
}

View File

@ -2,22 +2,18 @@ package com.bytezone.diskbrowser.visicalc;
class IsError extends Function
{
boolean firstTime = true;
Cell cell;
Expression expression;
public IsError (Sheet parent, String text)
{
super (parent, text);
expression = new Expression (parent, functionText);
}
@Override
public double getValue ()
public void calculate ()
{
if (firstTime)
{
firstTime = false;
cell = parent.getCell (new Address (functionText));
}
return cell == null ? 1 : 0;
value = expression.getValue ();
isError = expression.isError ();
}
}

View File

@ -2,15 +2,18 @@ package com.bytezone.diskbrowser.visicalc;
public class IsNa extends Function
{
Expression expression;
IsNa (Sheet parent, String text)
{
super (parent, text);
expression = new Expression (parent, functionText);
}
@Override
public double getValue ()
public void calculate ()
{
return 0;
value = expression.getValue ();
isError = expression.isError ();
}
}

View File

@ -3,7 +3,7 @@ package com.bytezone.diskbrowser.visicalc;
class Lookup extends Function
{
Range range;
boolean hasValue;
// boolean hasValue;
String sourceText;
String rangeText;
Expression source;
@ -21,14 +21,13 @@ class Lookup extends Function
}
// need a mechanism to return NA and ERROR
@Override
public boolean hasValue ()
{
return hasValue;
}
// @Override
// public boolean hasValue ()
// {
// return hasValue;
// }
@Override
public double getValue ()
public void calculate ()
{
double sourceValue = source.getValue ();
@ -43,10 +42,10 @@ class Lookup extends Function
if (target != null)
if (range.isVertical ())
return parent.getCell (target.nextColumn ()).getValue ();
value = parent.getCell (target.nextColumn ()).getValue ();
else
return parent.getCell (target.nextRow ()).getValue ();
value = parent.getCell (target.nextRow ()).getValue ();
return 0;
// return 0;
}
}

View File

@ -3,8 +3,6 @@ package com.bytezone.diskbrowser.visicalc;
class Max extends Function
{
private final Range range;
private boolean hasChecked;
private double max = Double.MIN_VALUE;
public Max (Sheet parent, String text)
{
@ -13,34 +11,31 @@ class Max extends Function
}
@Override
public boolean hasValue ()
public void calculate ()
{
if (!hasChecked)
calculate ();
return hasValue;
}
@Override
public double getValue ()
{
return hasValue () ? max : 0;
}
private void calculate ()
{
hasChecked = true;
hasValue = false;
value = Double.MIN_VALUE;
isError = false;
int totalChecked = 0;
for (Address address : range)
{
Cell cell = parent.getCell (address);
if (cell != null && cell.hasValue ())
if (cell == null)
continue;
if (cell.isError () || cell.isNaN ())
{
hasValue = true;
double value = cell.getValue ();
if (value > max)
max = value;
isError = true;
break;
}
double temp = cell.getValue ();
if (temp > value)
value = temp;
totalChecked++;
}
if (totalChecked == 0)
isError = true;
}
}

View File

@ -3,8 +3,6 @@ package com.bytezone.diskbrowser.visicalc;
class Min extends Function
{
private final Range range;
private boolean hasChecked;
private double min = Double.MAX_VALUE;
public Min (Sheet parent, String text)
{
@ -13,34 +11,31 @@ class Min extends Function
}
@Override
public boolean hasValue ()
public void calculate ()
{
if (!hasChecked)
calculate ();
return hasValue;
}
@Override
public double getValue ()
{
return hasValue () ? min : 0;
}
private void calculate ()
{
hasChecked = true;
hasValue = false;
value = Double.MAX_VALUE;
isError = false;
int totalChecked = 0;
for (Address address : range)
{
Cell cell = parent.getCell (address);
if (cell != null && cell.hasValue ())
if (cell == null)
continue;
if (cell.isError () || cell.isNaN ())
{
hasValue = true;
double value = cell.getValue ();
if (value < min)
min = value;
isError = true;
break;
}
double temp = cell.getValue ();
if (temp < value)
value = temp;
totalChecked++;
}
if (totalChecked == 0)
isError = true;
}
}

View File

@ -8,15 +8,15 @@ public class Na extends Function
}
@Override
public boolean hasValue ()
public boolean isError ()
{
return false;
return true;
}
@Override
public String getError ()
public boolean isNaN ()
{
return "@NA";
return true;
}
@Override
@ -24,4 +24,9 @@ public class Na extends Function
{
return 0;
}
@Override
public void calculate ()
{
}
}

View File

@ -8,9 +8,6 @@ public class Npv extends Function
private final Expression valueExp;
private final Range range;
private boolean hasChecked;
private final double value = 0;
Npv (Sheet parent, String text)
{
super (parent, text);
@ -24,32 +21,23 @@ public class Npv extends Function
}
@Override
public boolean hasValue ()
public void calculate ()
{
if (!hasChecked)
calculate ();
return hasValue;
}
@Override
public double getValue ()
{
return hasValue () ? value : 0;
}
private void calculate ()
{
hasChecked = true;
hasValue = false;
value = 0;
for (Address address : range)
{
Cell cell = parent.getCell (address);
if (cell != null && cell.hasValue ())
if (cell == null)
continue;
if (cell.isError () || cell.isNaN ())
{
hasValue = true;
// calculate something
isError = true;
break;
}
double temp = cell.getValue ();
}
}
}

View File

@ -2,26 +2,37 @@ package com.bytezone.diskbrowser.visicalc;
class Number implements Value
{
private double value;
private boolean hasValue;
double value;
boolean isError;
public Number (String text)
{
try
{
this.value = Double.parseDouble (text);
hasValue = true;
value = Double.parseDouble (text);
}
catch (NumberFormatException e)
{
hasValue = false;
isError = true;
}
}
@Override
public boolean hasValue ()
public boolean isError ()
{
return hasValue;
return isError;
}
@Override
public boolean isNaN ()
{
return Double.isNaN (value);
}
@Override
public String toString ()
{
return String.format ("Number: %f", value);
}
@Override
@ -31,14 +42,13 @@ class Number implements Value
}
@Override
public String getError ()
public String getText ()
{
return hasValue ? "" : "@NA";
return null;
}
@Override
public String toString ()
public void calculate ()
{
return String.format ("Number: %f", value);
}
}

View File

@ -9,8 +9,8 @@ class Or extends Function
}
@Override
public double getValue ()
public void calculate ()
{
return 0;
value = 0;
}
}

View File

@ -8,8 +8,8 @@ class Pi extends Function
}
@Override
public double getValue ()
public void calculate ()
{
return 3.1415926536;
value = 3.1415926536;
}
}

View File

@ -14,6 +14,7 @@ public class Sheet
private static final Pattern addressPattern =
Pattern.compile ("([AB]?[A-Z])([0-9]{1,3}):");
private static final byte END_OF_LINE_TOKEN = (byte) 0x8D;
private static final int FORMAT_LENGTH = 3;
private final Map<Integer, Cell> rowOrderCells = new TreeMap<Integer, Cell> ();
private final Map<Integer, Cell> columnOrderCells = new TreeMap<Integer, Cell> ();
@ -266,7 +267,8 @@ public class Sheet
String format = "";
while (line.startsWith ("/"))
{
String fmt = line.substring (0, 3);
String fmt = line.substring (0, FORMAT_LENGTH);
line = line.substring (FORMAT_LENGTH);
if (fmt.equals ("/TH") || fmt.equals ("/TV")) // lock titles ??
{
@ -275,7 +277,6 @@ public class Sheet
else
currentCell.format (fmt); // formatting command
line = line.substring (3);
format += fmt;
}

View File

@ -3,8 +3,6 @@ package com.bytezone.diskbrowser.visicalc;
class Sum extends Function
{
private final Range range;
private boolean hasChecked;
private double sum = 0;
public Sum (Sheet parent, String text)
{
@ -13,32 +11,21 @@ class Sum extends Function
}
@Override
public boolean hasValue ()
{
if (!hasChecked)
calculate ();
return hasValue;
}
@Override
public double getValue ()
{
return hasValue () ? sum : 0;
}
public void calculate ()
{
hasChecked = true;
hasValue = false;
value = 0;
for (Address address : range)
{
Cell cell = parent.getCell (address);
if (cell != null && cell.hasValue ())
if (cell == null)
continue;
if (cell.isError () || cell.isNaN ())
{
hasValue = true;
sum += cell.getValue ();
isError = true;
break;
}
value += cell.getValue ();
}
}
}

View File

@ -2,9 +2,15 @@ package com.bytezone.diskbrowser.visicalc;
interface Value
{
public boolean hasValue ();
// public boolean hasValue ();
public double getValue ();
public String getError ();
public String getText ();
public boolean isError ();
public boolean isNaN ();
public void calculate ();
}