From 01d56941f6e90bf6166bd0cbb709e3784a853ba5 Mon Sep 17 00:00:00 2001 From: Denis Molony Date: Sun, 26 Feb 2017 21:44:10 +1100 Subject: [PATCH] Condition is a Value --- .../bytezone/diskbrowser/visicalc/And.java | 5 +- .../diskbrowser/visicalc/Average.java | 45 +++++++++++++ .../bytezone/diskbrowser/visicalc/Cell.java | 16 +++-- .../bytezone/diskbrowser/visicalc/Choose.java | 26 ++++++++ .../diskbrowser/visicalc/Condition.java | 39 +++++++---- .../diskbrowser/visicalc/Function.java | 65 ++++++++++--------- src/com/bytezone/diskbrowser/visicalc/If.java | 4 +- src/com/bytezone/diskbrowser/visicalc/Or.java | 5 +- .../bytezone/diskbrowser/visicalc/Sheet.java | 12 +++- 9 files changed, 162 insertions(+), 55 deletions(-) create mode 100644 src/com/bytezone/diskbrowser/visicalc/Average.java create mode 100644 src/com/bytezone/diskbrowser/visicalc/Choose.java diff --git a/src/com/bytezone/diskbrowser/visicalc/And.java b/src/com/bytezone/diskbrowser/visicalc/And.java index 4e5746e..9630b9d 100644 --- a/src/com/bytezone/diskbrowser/visicalc/And.java +++ b/src/com/bytezone/diskbrowser/visicalc/And.java @@ -19,11 +19,14 @@ class And extends Function public Value calculate () { for (Condition condition : conditions) - if (!condition.getResult ()) + { + condition.calculate (); + if (condition.getValue () == 0) { value = 0; return this; } + } value = 1; return this; } diff --git a/src/com/bytezone/diskbrowser/visicalc/Average.java b/src/com/bytezone/diskbrowser/visicalc/Average.java new file mode 100644 index 0000000..9853708 --- /dev/null +++ b/src/com/bytezone/diskbrowser/visicalc/Average.java @@ -0,0 +1,45 @@ +package com.bytezone.diskbrowser.visicalc; + +public class Average extends Function +{ + private final Range range; + + public Average (Sheet parent, String text) + { + super (parent, text); + range = new Range (text); + } + + @Override + public Value calculate () + { + double total = 0.0; + int totalChecked = 0; + + for (Address address : range) + { + Cell cell = parent.getCell (address); + if (cell == null || cell.isValueType (ValueType.NA)) + continue; + + if (!cell.isValueType (ValueType.VALUE)) + { + valueType = cell.getValueType (); + break; + } + + total += cell.getValue (); + totalChecked++; + } + + if (totalChecked == 0) + valueType = ValueType.NA; + else + { + value = total / totalChecked; + valueType = ValueType.VALUE; + } + + return this; + } +} \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Cell.java b/src/com/bytezone/diskbrowser/visicalc/Cell.java index 89366bd..f3df7d5 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Cell.java +++ b/src/com/bytezone/diskbrowser/visicalc/Cell.java @@ -5,6 +5,7 @@ class Cell extends AbstractValue implements Comparable // private static final DecimalFormat nf = new DecimalFormat ("#####0.00"); private static final String line = "+----------------------------------------" + "--------------------------------------------+"; + private static final String empty = " "; private final Address address; private final Sheet parent; @@ -47,7 +48,7 @@ class Cell extends AbstractValue implements Comparable // /FR - right justified // /F* - graph (histogram) - if (formatText.equals ("/TH") || formatText.equals ("/TV")) // lock titles + if (formatText.startsWith ("/T")) // lock titles return; if (formatText.startsWith ("/F")) @@ -138,7 +139,7 @@ class Cell extends AbstractValue implements Comparable return format.justify (repeat, colWidth, ' '); case EMPTY: - return ""; + return format.justify (empty, colWidth, ' '); case VALUE: if (value == null) @@ -200,9 +201,7 @@ class Cell extends AbstractValue implements Comparable if (expressionText == null) expressionText = ""; - Expression expression = new Expression (parent, expressionText); - // value = expression.size () == 1 ? expression.get (0) : expression; - value = expression.reduce (); + value = new Expression (parent, expressionText).reduce (); } value.calculate (); @@ -278,6 +277,13 @@ class Cell extends AbstractValue implements Comparable for (Value v : (Function) value) text.append (getValueText (v, depth + 1)); } + else if (value instanceof Condition) + { + text.append ( + String.format ("| Condition : %-69s |%n", ((Condition) value).fullText)); + for (Value v : (Condition) value) + text.append (getValueText (v, depth + 1)); + } return text.toString (); } diff --git a/src/com/bytezone/diskbrowser/visicalc/Choose.java b/src/com/bytezone/diskbrowser/visicalc/Choose.java new file mode 100644 index 0000000..3609006 --- /dev/null +++ b/src/com/bytezone/diskbrowser/visicalc/Choose.java @@ -0,0 +1,26 @@ +package com.bytezone.diskbrowser.visicalc; + +public class Choose extends Function +{ + protected final Range range; + String sourceText; + String rangeText; + Number source; + + Choose (Sheet parent, String text) + { + super (parent, text); + + int pos = text.indexOf (','); + sourceText = text.substring (8, pos); + rangeText = text.substring (pos + 1, text.length () - 1); + range = new Range (rangeText); + source = new Number (sourceText); + } + + @Override + public Value calculate () + { + return null; + } +} \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Condition.java b/src/com/bytezone/diskbrowser/visicalc/Condition.java index 06fbdff..995e4ab 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Condition.java +++ b/src/com/bytezone/diskbrowser/visicalc/Condition.java @@ -1,9 +1,9 @@ package com.bytezone.diskbrowser.visicalc; -import com.bytezone.diskbrowser.visicalc.Value.ValueType; +import java.util.Iterator; // Predicate -class Condition //extends AbstractValue +class Condition extends AbstractValue implements Iterable { private static final String[] comparators = { "<>", "<=", ">=", "=", "<", ">" }; @@ -12,14 +12,16 @@ class Condition //extends AbstractValue private String comparator; private String conditionText; private String valueText; + protected String fullText; private Expression conditionExpression; private Expression valueExpression; public Condition (Sheet parent, String text) { - // super ("Condition"); + super ("Cond"); this.parent = parent; + fullText = text; for (String comp : comparators) { @@ -46,8 +48,11 @@ class Condition //extends AbstractValue } } - public boolean getResult () + @Override + public Value calculate () { + value = 0; + if (conditionExpression == null) { conditionExpression = new Expression (parent, conditionText); @@ -56,33 +61,33 @@ class Condition //extends AbstractValue conditionExpression.calculate (); valueExpression.calculate (); - // expressions.add (conditionExpression); - // expressions.add (valueExpression); + values.add (conditionExpression); + values.add (valueExpression); } if (conditionExpression.isValueType (ValueType.ERROR) || valueExpression.isValueType (ValueType.ERROR)) - return false; + return this; double conditionResult = conditionExpression.getValue (); double valueResult = valueExpression.getValue (); if (comparator.equals ("=")) - return conditionResult == valueResult; + value = conditionResult == valueResult ? 1 : 0; else if (comparator.equals ("<>")) - return conditionResult != valueResult; + value = conditionResult != valueResult ? 1 : 0; else if (comparator.equals ("<")) - return conditionResult < valueResult; + value = conditionResult < valueResult ? 1 : 0; else if (comparator.equals (">")) - return conditionResult > valueResult; + value = conditionResult > valueResult ? 1 : 0; else if (comparator.equals ("<=")) - return conditionResult <= valueResult; + value = conditionResult <= valueResult ? 1 : 0; else if (comparator.equals (">=")) - return conditionResult >= valueResult; + value = conditionResult >= valueResult ? 1 : 0; else System.out.printf ("Unexpected comparator result [%s]%n", comparator); - return false; // flag error? + return this; } @Override @@ -91,4 +96,10 @@ class Condition //extends AbstractValue return String.format ("[cond=%s, op=%s, value=%s]", conditionText, comparator, valueText); } + + @Override + public Iterator iterator () + { + return values.iterator (); + } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Function.java b/src/com/bytezone/diskbrowser/visicalc/Function.java index 3a2ec32..e4aaaef 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Function.java +++ b/src/com/bytezone/diskbrowser/visicalc/Function.java @@ -23,7 +23,6 @@ import java.util.Iterator; // @TAN // @ATAN -// should Function extend Expression? should it be Iterable? abstract class Function extends AbstractValue implements Iterable { protected final Sheet parent; @@ -31,8 +30,6 @@ abstract class Function extends AbstractValue implements Iterable protected String functionText; protected String fullText; - // protected List values = new ArrayList (); - static Function getInstance (Sheet parent, String text) { if (text.charAt (0) != '@') @@ -41,35 +38,26 @@ abstract class Function extends AbstractValue implements Iterable return new Error (parent, "@ERROR"); } - if (text.startsWith ("@LOOKUP(")) - return new Lookup (parent, text); - - if (text.startsWith ("@COUNT(")) - return new Count (parent, text); - - if (text.startsWith ("@MIN(")) - return new Min (parent, text); - - if (text.startsWith ("@MAX(")) - return new Max (parent, text); - - if (text.startsWith ("@SUM(")) - return new Sum (parent, text); - - if (text.startsWith ("@IF(")) - return new If (parent, text); - - if (text.startsWith ("@OR(")) - return new Or (parent, text); + if (text.startsWith ("@ABS(")) + return new Abs (parent, text); if (text.startsWith ("@AND(")) return new And (parent, text); - if (text.startsWith ("@NPV(")) - return new Npv (parent, text); + if (text.startsWith ("@AVERAGE(")) + return new Average (parent, text); - if (text.startsWith ("@ABS(")) - return new Abs (parent, text); + if (text.startsWith ("@COUNT(")) + return new Count (parent, text); + + if (text.startsWith ("@CHOOSE(")) + return new Choose (parent, text); + + if (text.startsWith ("@ERROR")) + return new Error (parent, text); + + if (text.startsWith ("@IF(")) + return new If (parent, text); if (text.startsWith ("@INT(")) return new Int (parent, text); @@ -80,15 +68,30 @@ abstract class Function extends AbstractValue implements Iterable if (text.startsWith ("@ISNA(")) return new IsNa (parent, text); - if (text.startsWith ("@PI")) - return new Pi (parent, text); + if (text.startsWith ("@LOOKUP(")) + return new Lookup (parent, text); - if (text.startsWith ("@ERROR")) - return new Error (parent, text); + if (text.startsWith ("@MIN(")) + return new Min (parent, text); + + if (text.startsWith ("@MAX(")) + return new Max (parent, text); if (text.equals ("@NA")) return new Na (parent, text); + if (text.startsWith ("@NPV(")) + return new Npv (parent, text); + + if (text.startsWith ("@OR(")) + return new Or (parent, text); + + if (text.startsWith ("@PI")) + return new Pi (parent, text); + + if (text.startsWith ("@SUM(")) + return new Sum (parent, text); + System.out.printf ("Unknown function: [%s]%n", text); return new Error (parent, "@ERROR"); } diff --git a/src/com/bytezone/diskbrowser/visicalc/If.java b/src/com/bytezone/diskbrowser/visicalc/If.java index 7008752..5c8ca59 100644 --- a/src/com/bytezone/diskbrowser/visicalc/If.java +++ b/src/com/bytezone/diskbrowser/visicalc/If.java @@ -17,6 +17,7 @@ class If extends Function int pos2 = functionText.indexOf (',', pos1 + 1); condition = new Condition (parent, functionText.substring (0, pos1)); + values.add (condition); textTrue = functionText.substring (pos1 + 1, pos2); textFalse = functionText.substring (pos2 + 1); @@ -26,8 +27,9 @@ class If extends Function public Value calculate () { valueType = ValueType.VALUE; + condition.calculate (); - if (condition.getResult ()) + if (condition.getValue () == 1) { if (expTrue == null) { diff --git a/src/com/bytezone/diskbrowser/visicalc/Or.java b/src/com/bytezone/diskbrowser/visicalc/Or.java index 1f37291..acc6fd2 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Or.java +++ b/src/com/bytezone/diskbrowser/visicalc/Or.java @@ -19,11 +19,14 @@ class Or extends Function public Value calculate () { for (Condition condition : conditions) - if (condition.getResult ()) + { + condition.calculate (); + if (condition.getValue () == 1) { value = 1; return this; } + } value = 0; return this; } diff --git a/src/com/bytezone/diskbrowser/visicalc/Sheet.java b/src/com/bytezone/diskbrowser/visicalc/Sheet.java index 95c1976..df72527 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Sheet.java +++ b/src/com/bytezone/diskbrowser/visicalc/Sheet.java @@ -61,6 +61,7 @@ public class Sheet // /GRA Recalculation Auto // /GO Global // /GOC Calculation Order - Columns first + // /GOR Calculation Order - Rows first // /T Titles (HVBN) // /TH fix Horizontal Titles @@ -138,6 +139,8 @@ public class Sheet /- REPEATING LABEL */ + // /X!/X>A3:>A7: A3:top-left cell in window, A7:cell to place cursor + public Sheet (byte[] buffer) { int last = buffer.length; @@ -382,6 +385,8 @@ public class Sheet for (Cell cell : rowOrderCells.values ()) { Address cellAddress = cell.getAddress (); + + // insert newlines for empty rows while (lastRow < cellAddress.row) { ++lastRow; @@ -392,6 +397,7 @@ public class Sheet text.append ("\n"); } + // pad out empty columns while (lastColumn < cellAddress.column) { int width = columnWidth; @@ -418,8 +424,10 @@ public class Sheet { if (last < cell.getAddress ().column) { - text.append ("\n *** Column " - + cell.getAddress ().column + " ***\n\n"); + String columnName = Address.getCellName (1, cell.getAddress ().column); + columnName = columnName.substring (0, columnName.length () - 1); + text.append ("\n *** Column " + columnName + + " ***\n\n"); last = cell.getAddress ().column; } text.append (cell.getDebugText ());