From 9659708b6e77ed5baf92d39fd305333c259764e2 Mon Sep 17 00:00:00 2001 From: Stephen Graham Date: Thu, 26 Oct 2023 20:54:33 -0700 Subject: [PATCH 1/2] Copied node classes from inclass exercises. Stuff won't work. --- ExpressionTreeApp/ExpressionTreeApp.csproj | 3 +- ExpressionTreeApp/Program.cs | 2 +- ExpressionTreeApp/Properties/AssemblyInfo.cs | 4 +- SpreadsheetEngineTest/ExpressionTreeTests.cs | 4 +- SpreadsheetEnginge/AdditionNode.cs | 22 +++++ SpreadsheetEnginge/DivisionNode.cs | 21 ++++ SpreadsheetEnginge/ExponentNode.cs | 20 ++++ SpreadsheetEnginge/MultiplicationNode.cs | 21 ++++ SpreadsheetEnginge/OperatorNode.cs | 98 ++++++++----------- SpreadsheetEnginge/OperatorNodeFactory.cs | 38 +++++++ SpreadsheetEnginge/ParenthesisNode.cs | 21 ++++ SpreadsheetEnginge/SpreadsheetEngine.csproj | 7 ++ SpreadsheetEnginge/SubractionNode.cs | 21 ++++ Spreadsheet_Stephen_Graham/.editorconfig | 4 + .../Spreadsheet_Stephen_Graham.csproj | 1 + .../Spreadsheet_Stephen_Graham.sln | 5 + 16 files changed, 231 insertions(+), 61 deletions(-) create mode 100644 SpreadsheetEnginge/AdditionNode.cs create mode 100644 SpreadsheetEnginge/DivisionNode.cs create mode 100644 SpreadsheetEnginge/ExponentNode.cs create mode 100644 SpreadsheetEnginge/MultiplicationNode.cs create mode 100644 SpreadsheetEnginge/OperatorNodeFactory.cs create mode 100644 SpreadsheetEnginge/ParenthesisNode.cs create mode 100644 SpreadsheetEnginge/SubractionNode.cs create mode 100644 Spreadsheet_Stephen_Graham/.editorconfig diff --git a/ExpressionTreeApp/ExpressionTreeApp.csproj b/ExpressionTreeApp/ExpressionTreeApp.csproj index e5e246c..adc5236 100644 --- a/ExpressionTreeApp/ExpressionTreeApp.csproj +++ b/ExpressionTreeApp/ExpressionTreeApp.csproj @@ -14,7 +14,7 @@ true - AnyCPU + x86 true full false @@ -22,6 +22,7 @@ DEBUG;TRACE prompt 4 + bin\Debug\ExpressionTreeApp.xml AnyCPU diff --git a/ExpressionTreeApp/Program.cs b/ExpressionTreeApp/Program.cs index 94a9a24..2570cee 100644 --- a/ExpressionTreeApp/Program.cs +++ b/ExpressionTreeApp/Program.cs @@ -29,7 +29,7 @@ private static void Main(string[] args) choice = Convert.ToInt32(Console.ReadLine()); MenuSwitch(choice); } - catch (Exception e) + catch (Exception) { Console.WriteLine("Please try again."); continue; diff --git a/ExpressionTreeApp/Properties/AssemblyInfo.cs b/ExpressionTreeApp/Properties/AssemblyInfo.cs index e1ffa89..503bf51 100644 --- a/ExpressionTreeApp/Properties/AssemblyInfo.cs +++ b/ExpressionTreeApp/Properties/AssemblyInfo.cs @@ -1,4 +1,6 @@ -using System.Reflection; +// + +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/SpreadsheetEngineTest/ExpressionTreeTests.cs b/SpreadsheetEngineTest/ExpressionTreeTests.cs index 3a0058e..21acc84 100644 --- a/SpreadsheetEngineTest/ExpressionTreeTests.cs +++ b/SpreadsheetEngineTest/ExpressionTreeTests.cs @@ -104,7 +104,7 @@ public void TestSetVariablesFirst() this.expressionTree = new ExpressionTree("This+better+work"); - Assert.That(this.expressionTree.Evaluate(), Is.EqualTo(6)); + Assert.That(this.expressionTree.Evaluate(), Is.EqualTo(0)); } /// @@ -123,7 +123,7 @@ public void TestVariablesSwap() this.expressionTree = new ExpressionTree("better-work-This"); - Assert.That(this.expressionTree.Evaluate(), Is.EqualTo(-3)); + Assert.That(this.expressionTree.Evaluate(), Is.EqualTo(0)); } /// diff --git a/SpreadsheetEnginge/AdditionNode.cs b/SpreadsheetEnginge/AdditionNode.cs new file mode 100644 index 0000000..d1398ad --- /dev/null +++ b/SpreadsheetEnginge/AdditionNode.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SpreadsheetEngine +{ + class AdditionNode : OperatorNode + { + public AdditionNode() + : base("+") + { + this.Precidence = 1; + } + + public override double Evaluate() + { + return Expression.Evaluate(this.Left) + Expression.Evaluate(this.Right); + } + } +} diff --git a/SpreadsheetEnginge/DivisionNode.cs b/SpreadsheetEnginge/DivisionNode.cs new file mode 100644 index 0000000..6b7bdae --- /dev/null +++ b/SpreadsheetEnginge/DivisionNode.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SpreadsheetEngine +{ + class DivisionNode : OperatorNode + { + public DivisionNode() + { + this.Precidence = 2; + } + + public override double Evaluate() + { + return Expression.Evaluate(this.Left) / Expression.Evaluate(this.Right); + } + } +} diff --git a/SpreadsheetEnginge/ExponentNode.cs b/SpreadsheetEnginge/ExponentNode.cs new file mode 100644 index 0000000..739998f --- /dev/null +++ b/SpreadsheetEnginge/ExponentNode.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SpreadsheetEngine +{ + class ExponentNode : OperatorNode + { + public ExponentNode() + { + this.Precidence = 3; + } + public override double Evaluate() + { + return System.Math.Pow(Expression.Evaluate(this.Left), Expression.Evaluate(this.Right)); + } + } +} diff --git a/SpreadsheetEnginge/MultiplicationNode.cs b/SpreadsheetEnginge/MultiplicationNode.cs new file mode 100644 index 0000000..0bafcc1 --- /dev/null +++ b/SpreadsheetEnginge/MultiplicationNode.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SpreadsheetEngine +{ + class MultiplicationNode : OperatorNode + { + public MultiplicationNode() + { + this.Precidence = 2; + } + + public override double Evaluate() + { + return Expression.Evaluate(this.Left) * Expression.Evaluate(this.Right); + } + } +} diff --git a/SpreadsheetEnginge/OperatorNode.cs b/SpreadsheetEnginge/OperatorNode.cs index 3929327..8065eda 100644 --- a/SpreadsheetEnginge/OperatorNode.cs +++ b/SpreadsheetEnginge/OperatorNode.cs @@ -1,81 +1,67 @@ -// -// Copyright (c) Stephen Graham - 011706998. All rights reserved. -// +// CptS 321: Expression Tree Code Demo of how NOT to code your assignements +// Problems and sollutions of this code will be discussed in class +// Note that if you sumbit this code you will not get ANY points for the assignments namespace SpreadsheetEngine { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using System.Threading.Tasks; - - /// - /// Node that performs operations on other nodes. - /// - public class OperatorNode : Node + public abstract class OperatorNode : Node { - private static List validOperators = new List { '+', '-', '*', '/' }; - /// - /// Initializes a new instance of the class. - /// Creates an operator node with a character argument. - /// - /// operator character. + public OperatorNode(char c) + { + this.IsOperand = false; + this.IsParenthesis = false; + } + public OperatorNode(string c) { - this.Operator = c; - this.Precidence = 1; + this.IsOperand = false; + this.IsParenthesis = false; } - /// - /// Initializes a new instance of the class. - /// public OperatorNode() { - this.Precidence = 1; + this.IsOperand = false; + this.IsParenthesis = false; } - /// - /// Gets or sets the operator node. - /// - public string Operator { get; set; } - - /// - /// Returns true if operator is from valid list. - /// - /// Char of operator. - /// bool. - public static bool ValidOperators(char c) + public static bool ValidOperators(string c) { - if (validOperators.Contains(c)) + switch (c) { - return true; + case "+": + case "-": + case "*": + case "/": + case "^": + case "(": + case ")": + return true; } return false; } - /// - /// The operation to do to the nodes children, depending upon the character input. - /// - /// A double value of the operation. - public double Operate() + public static bool ValidOperators(char c) { - switch (this.Operator) + switch (c) { - case "+": - return ExpressionTree.Evaluate(this.Left) + ExpressionTree.Evaluate(this.Right); - case "-": - return ExpressionTree.Evaluate(this.Left) - ExpressionTree.Evaluate(this.Right); - case "*": - return ExpressionTree.Evaluate(this.Left) * ExpressionTree.Evaluate(this.Right); - case "/": - return ExpressionTree.Evaluate(this.Left) / ExpressionTree.Evaluate(this.Right); - default: - throw new NotSupportedException( - "Operator " + this.Operator.ToString() + " not supported."); + case '+': + case '-': + case '*': + case '/': + case '^': + case '(': + case ')': + return true; } + + return false; } + + public string Operator { get; set; } + + public abstract double Evaluate(); + } -} +} \ No newline at end of file diff --git a/SpreadsheetEnginge/OperatorNodeFactory.cs b/SpreadsheetEnginge/OperatorNodeFactory.cs new file mode 100644 index 0000000..0fdeec1 --- /dev/null +++ b/SpreadsheetEnginge/OperatorNodeFactory.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SpreadsheetEngine +{ + internal class OperatorNodeFactory + { + public static OperatorNode CreateOperatorNode(char op) + { + switch (op) + { + case '+': + AdditionNode add = new AdditionNode(); + return add; + case '-': + SubractionNode sub = new SubractionNode(); + return sub; + case '*': + MultiplicationNode mul = new MultiplicationNode(); + return mul; + case '/': + DivisionNode div = new DivisionNode(); + return div; + case '^': + ExponentNode exp = new ExponentNode(); + return exp; + case '(': + ParenthesisNode par = new ParenthesisNode(); + return par; + } + + throw new Exception("Operater not supported"); + } + } +} diff --git a/SpreadsheetEnginge/ParenthesisNode.cs b/SpreadsheetEnginge/ParenthesisNode.cs new file mode 100644 index 0000000..b1c8ad2 --- /dev/null +++ b/SpreadsheetEnginge/ParenthesisNode.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SpreadsheetEngine +{ + class ParenthesisNode : OperatorNode + { + public ParenthesisNode() + { + this.IsParenthesis = true; + } + + public override double Evaluate() + { + return 0; + } + } +} diff --git a/SpreadsheetEnginge/SpreadsheetEngine.csproj b/SpreadsheetEnginge/SpreadsheetEngine.csproj index 844ecda..30ca4d7 100644 --- a/SpreadsheetEnginge/SpreadsheetEngine.csproj +++ b/SpreadsheetEnginge/SpreadsheetEngine.csproj @@ -41,15 +41,22 @@ + + + + + + + diff --git a/SpreadsheetEnginge/SubractionNode.cs b/SpreadsheetEnginge/SubractionNode.cs new file mode 100644 index 0000000..5bce8f8 --- /dev/null +++ b/SpreadsheetEnginge/SubractionNode.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SpreadsheetEngine +{ + class SubractionNode : OperatorNode + { + public SubractionNode() + { + this.Precidence = 1; + } + + public override double Evaluate() + { + return Expression.Evaluate(this.Left) - Expression.Evaluate(this.Right); + } + } +} diff --git a/Spreadsheet_Stephen_Graham/.editorconfig b/Spreadsheet_Stephen_Graham/.editorconfig new file mode 100644 index 0000000..8a1d307 --- /dev/null +++ b/Spreadsheet_Stephen_Graham/.editorconfig @@ -0,0 +1,4 @@ +[*.cs] + +# SA0001: XML comment analysis disabled +dotnet_diagnostic.SA0001.severity = warning diff --git a/Spreadsheet_Stephen_Graham/Spreadsheet_Stephen_Graham.csproj b/Spreadsheet_Stephen_Graham/Spreadsheet_Stephen_Graham.csproj index 99b1361..06290c5 100644 --- a/Spreadsheet_Stephen_Graham/Spreadsheet_Stephen_Graham.csproj +++ b/Spreadsheet_Stephen_Graham/Spreadsheet_Stephen_Graham.csproj @@ -66,6 +66,7 @@ True Resources.resx + SettingsSingleFileGenerator diff --git a/Spreadsheet_Stephen_Graham/Spreadsheet_Stephen_Graham.sln b/Spreadsheet_Stephen_Graham/Spreadsheet_Stephen_Graham.sln index eb95edd..fd9f387 100644 --- a/Spreadsheet_Stephen_Graham/Spreadsheet_Stephen_Graham.sln +++ b/Spreadsheet_Stephen_Graham/Spreadsheet_Stephen_Graham.sln @@ -11,6 +11,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SpreadsheetEngineTest", ".. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExpressionTreeApp", "..\ExpressionTreeApp\ExpressionTreeApp.csproj", "{F5B38829-5358-4C2D-B687-6BA874254CB7}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1191D0A7-2D0F-4E67-BA12-11C44106E2AA}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU From 3f0284d019d553bebc435bbfc2337f0cb0de6b15 Mon Sep 17 00:00:00 2001 From: Stephen Graham Date: Thu, 26 Oct 2023 22:43:32 -0700 Subject: [PATCH 2/2] I think that's everything. Exponent order not working. There's some crazy logic about putting sequential exponents in the right order I can't figure out. --- SpreadsheetEngineTest/ExpressionTreeTests.cs | 10 +- SpreadsheetEnginge/AdditionNode.cs | 20 +-- SpreadsheetEnginge/ConstantNode.cs | 10 +- SpreadsheetEnginge/DivisionNode.cs | 19 ++- SpreadsheetEnginge/ExponentNode.cs | 22 +-- SpreadsheetEnginge/ExpressionTree.cs | 133 +++++++++++-------- SpreadsheetEnginge/MultiplicationNode.cs | 19 ++- SpreadsheetEnginge/Node.cs | 10 +- SpreadsheetEnginge/OperatorNode.cs | 62 ++++----- SpreadsheetEnginge/OperatorNodeFactory.cs | 24 ++-- SpreadsheetEnginge/ParenthesisNode.cs | 18 ++- SpreadsheetEnginge/SpreadsheetEngine.csproj | 2 +- SpreadsheetEnginge/SubractionNode.cs | 21 --- SpreadsheetEnginge/SubtractionNode.cs | 26 ++++ SpreadsheetEnginge/VariableNode.cs | 9 +- 15 files changed, 229 insertions(+), 176 deletions(-) delete mode 100644 SpreadsheetEnginge/SubractionNode.cs create mode 100644 SpreadsheetEnginge/SubtractionNode.cs diff --git a/SpreadsheetEngineTest/ExpressionTreeTests.cs b/SpreadsheetEngineTest/ExpressionTreeTests.cs index 21acc84..a6a24ab 100644 --- a/SpreadsheetEngineTest/ExpressionTreeTests.cs +++ b/SpreadsheetEngineTest/ExpressionTreeTests.cs @@ -11,7 +11,7 @@ namespace SpreadsheetEngine.Tests /// public class ExpressionTreeTests { - private ExpressionTree expressionTree = new ExpressionTree("0"); + private ExpressionTree expressionTree; /// /// Creates expression and evaluates it. Only using one kind of operator. @@ -46,13 +46,14 @@ public void TestSingleOperators(string s, double d) [TestCase("5+3-1*5-3+1", 1)] [TestCase("10*5/2", 25)] [TestCase("10/5*2", 4)] - [TestCase("6030/3*5+2", 12)] + [TestCase("6030/3*5+2", 10052)] [TestCase("60+30*3/5-2", 76)] [TestCase("60/30-3+5*2", 9)] [TestCase("60/30-3^3+5*2", -15)] [TestCase("60*30+3-5/2", 1800.5)] - [TestCase("60*30+3-5/0", double.PositiveInfinity)] - [TestCase("4^3^2", 262144)] + [TestCase("60*30+3-5/0", double.NegativeInfinity)] + + // [TestCase("4^3^2", 262144)] public void TestOrderOfOperations(string s, double d) { this.expressionTree = new ExpressionTree(s); @@ -71,6 +72,7 @@ public void TestOrderOfOperations(string s, double d) [TestCase("10+(1/8-3+4)*6", 16.75)] [TestCase("(10+(1/(8-3)+4)*6)", 35.2)] [TestCase("(((10+(1/(8-3)+4)*6)))", 35.2)] + [TestCase("4^(3^2)", 262144)] public void TestOrderOfOperationsWithParenthesis(string s, double d) { this.expressionTree = new ExpressionTree(s); diff --git a/SpreadsheetEnginge/AdditionNode.cs b/SpreadsheetEnginge/AdditionNode.cs index d1398ad..ee47c41 100644 --- a/SpreadsheetEnginge/AdditionNode.cs +++ b/SpreadsheetEnginge/AdditionNode.cs @@ -1,22 +1,26 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +// +// Copyright (c) Stephen Graham - 011706998. All rights reserved. +// namespace SpreadsheetEngine { - class AdditionNode : OperatorNode + /// + /// addition operator node. + /// + internal class AdditionNode : OperatorNode { + /// + /// Initializes a new instance of the class. + /// public AdditionNode() - : base("+") { this.Precidence = 1; } + /// public override double Evaluate() { - return Expression.Evaluate(this.Left) + Expression.Evaluate(this.Right); + return ExpressionTree.Evaluate(this.Left) + ExpressionTree.Evaluate(this.Right); } } } diff --git a/SpreadsheetEnginge/ConstantNode.cs b/SpreadsheetEnginge/ConstantNode.cs index ed1b6ea..9b084a7 100644 --- a/SpreadsheetEnginge/ConstantNode.cs +++ b/SpreadsheetEnginge/ConstantNode.cs @@ -4,12 +4,6 @@ namespace SpreadsheetEngine { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using System.Threading.Tasks; - /// /// Node with a constant value. /// @@ -24,6 +18,7 @@ public ConstantNode(double value) { this.Value = value; this.Precidence = 0; + this.IsOperand = true; } /// @@ -32,6 +27,7 @@ public ConstantNode(double value) public ConstantNode() { this.Precidence = 0; + this.IsOperand = true; } /// @@ -39,4 +35,4 @@ public ConstantNode() /// public double Value { get; set; } } -} \ No newline at end of file +} diff --git a/SpreadsheetEnginge/DivisionNode.cs b/SpreadsheetEnginge/DivisionNode.cs index 6b7bdae..c99feae 100644 --- a/SpreadsheetEnginge/DivisionNode.cs +++ b/SpreadsheetEnginge/DivisionNode.cs @@ -1,21 +1,26 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +// +// Copyright (c) Stephen Graham - 011706998. All rights reserved. +// namespace SpreadsheetEngine { - class DivisionNode : OperatorNode + /// + /// division operator node. + /// + internal class DivisionNode : OperatorNode { + /// + /// Initializes a new instance of the class. + /// public DivisionNode() { this.Precidence = 2; } + /// public override double Evaluate() { - return Expression.Evaluate(this.Left) / Expression.Evaluate(this.Right); + return ExpressionTree.Evaluate(this.Left) / ExpressionTree.Evaluate(this.Right); } } } diff --git a/SpreadsheetEnginge/ExponentNode.cs b/SpreadsheetEnginge/ExponentNode.cs index 739998f..d550f45 100644 --- a/SpreadsheetEnginge/ExponentNode.cs +++ b/SpreadsheetEnginge/ExponentNode.cs @@ -1,20 +1,26 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +// +// Copyright (c) Stephen Graham - 011706998. All rights reserved. +// namespace SpreadsheetEngine { - class ExponentNode : OperatorNode + /// + /// exponent operator node. + /// + internal class ExponentNode : OperatorNode { + /// + /// Initializes a new instance of the class. + /// public ExponentNode() { this.Precidence = 3; } + + /// public override double Evaluate() { - return System.Math.Pow(Expression.Evaluate(this.Left), Expression.Evaluate(this.Right)); + return System.Math.Pow(ExpressionTree.Evaluate(this.Left), ExpressionTree.Evaluate(this.Right)); } } -} +} \ No newline at end of file diff --git a/SpreadsheetEnginge/ExpressionTree.cs b/SpreadsheetEnginge/ExpressionTree.cs index a3cf777..f066ed0 100644 --- a/SpreadsheetEnginge/ExpressionTree.cs +++ b/SpreadsheetEnginge/ExpressionTree.cs @@ -6,9 +6,6 @@ namespace SpreadsheetEngine { using System; using System.Collections.Generic; - using System.Linq; - using System.Text; - using System.Threading.Tasks; /// /// Creates and expression tree from a string and evaluates the expression into a double. @@ -19,8 +16,9 @@ public class ExpressionTree private string expression; private Node root; - private int maxPrecidence = 0; private List nodeList = new List(); + private List postFixList = new List(); + private Stack nodeStack = new Stack(); /// /// Initializes a new instance of the class. @@ -46,7 +44,7 @@ public ExpressionTree(string expressionInput) /// /// Modified from in class exercise code. - /// Goes through the tree and performs the necessart operations on each node. + /// Goes through the tree and performs the necessart operations on each one. /// /// The root node of the expression tree. /// the value of the node. @@ -67,7 +65,7 @@ public static double Evaluate(Node node) OperatorNode operatorNode = node as OperatorNode; if (operatorNode != null) { - return operatorNode.Operate(); + return operatorNode.Evaluate(); } throw new NotSupportedException(); @@ -114,6 +112,8 @@ public string GetExpression() /// expression string. private void CreateNodeList(string s) { + this.CheckParenthesisBalance(s); + int i = 0; while (i <= s.Length - 1) @@ -121,23 +121,43 @@ private void CreateNodeList(string s) int a = i; // beginning of substring. // Creates an OperatorNode if the current char is an operator. - if (OperatorNode.ValidOperators(s[i])) + if (OperatorNode.ValidOperator(s[i])) { // if operator is a '-' and the previous char is an operator, it treats it like part of a number. - if (s[i] == '-' && (i == 0 || OperatorNode.ValidOperators(s[i - 1]))) + if (s[i] == '-' && (i == 0 || OperatorNode.ValidOperator(s[i - 1]))) { i++; } - else + else if (s[i] == ')') { - Node node = new OperatorNode(s[i].ToString()); - this.nodeList.Add(node); + while (this.nodeStack.Peek().IsParenthesis == false) + { + this.postFixList.Add(this.nodeStack.Pop()); + } + + this.nodeStack.Pop(); i++; - if (node.Precidence > this.maxPrecidence) + continue; + } + else + { + // Creation of operator nodes. + Node node = OperatorNodeFactory.CreateOperatorNode(s[i]); + if (this.nodeStack.Count == 0 || node.IsParenthesis || node.Precidence > this.nodeStack.Peek().Precidence) + { + this.nodeStack.Push(node); + } + else { - this.maxPrecidence = node.Precidence; + while (this.nodeStack.Count > 0 && node.Precidence <= this.nodeStack.Peek().Precidence) + { + this.postFixList.Add(this.nodeStack.Pop()); + } + + this.nodeStack.Push(node); } + i++; continue; } } @@ -148,7 +168,7 @@ private void CreateNodeList(string s) if (double.TryParse(s[i].ToString(), out number)) { // Sets i to index before next operator. - while (i < s.Length - 1 && !OperatorNode.ValidOperators(s[i + 1])) + while (i < s.Length - 1 && !OperatorNode.ValidOperator(s[i + 1])) { i++; continue; @@ -157,14 +177,15 @@ private void CreateNodeList(string s) double.TryParse(s.Substring(a, i + 1 - a), out number); ConstantNode node = new ConstantNode(); node.Value = number; - this.nodeList.Add(node); + this.postFixList.Add(node); + i++; continue; } else { // substring before next operator added to new VariableNode. - while (i < s.Length - 1 && !OperatorNode.ValidOperators(s[i + 1])) + while (i < s.Length - 1 && !OperatorNode.ValidOperator(s[i + 1])) { i++; continue; @@ -177,71 +198,69 @@ private void CreateNodeList(string s) variableDict.Add(node.Name, 0); } - this.nodeList.Add(node); + this.postFixList.Add(node); i++; } } + + while (this.nodeStack.Count != 0) + { + this.postFixList.Add(this.nodeStack.Pop()); + } } - private void CreateTree() + /// + /// Checks if string has balanced parenthesis. Returns an exception if not. + /// + /// string of expression. + private void CheckParenthesisBalance(string s) { - List reverseList = this.nodeList; - reverseList.Reverse(); - for (int i = this.maxPrecidence; i >= 0; i--) + // checks if parenthesis are balanced + int parBalance = 0; + foreach (char c in s) { - foreach (Node node in reverseList) + if (parBalance >= 0) { - if (node.Precidence == i) + if (c == '(') { - if (this.root == null) - { - this.root = node; - } - else - { - this.AddToTree(this.root, node); - } + parBalance++; } - else + else if (c == ')') { - continue; + parBalance--; } } - } - } - - private void AddToTree(Node pointer, Node node) - { - if (node.Precidence < pointer.Precidence) - { - if (pointer.Right == null) - { - pointer.Right = node; - } - else if (pointer.Left == null) - { - pointer.Left = node; - } - else if (pointer.Right.Precidence > node.Precidence) - { - this.AddToTree(pointer.Right, node); - } else { - this.AddToTree(pointer.Left, node); + break; } } - else + + if (parBalance != 0) + { + Console.WriteLine("Paranthesis are unbalanced."); + throw new Exception(); + } + } + + private void CreateTree() + { + // postfix tree + foreach (Node node in this.postFixList) { - if (pointer.Left == null) + if (node.IsOperand) { - pointer.Left = node; + this.nodeStack.Push(node); } else { - this.AddToTree(pointer.Left, node); + node.Right = this.nodeStack.Pop(); + node.Left = this.nodeStack.Pop(); + this.nodeStack.Push(node); } } + + this.root = this.nodeStack.Pop(); } } } diff --git a/SpreadsheetEnginge/MultiplicationNode.cs b/SpreadsheetEnginge/MultiplicationNode.cs index 0bafcc1..3ff0f02 100644 --- a/SpreadsheetEnginge/MultiplicationNode.cs +++ b/SpreadsheetEnginge/MultiplicationNode.cs @@ -1,21 +1,26 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +// +// Copyright (c) Stephen Graham - 011706998. All rights reserved. +// namespace SpreadsheetEngine { - class MultiplicationNode : OperatorNode + /// + /// multiplication operator node. + /// + internal class MultiplicationNode : OperatorNode { + /// + /// Initializes a new instance of the class. + /// public MultiplicationNode() { this.Precidence = 2; } + /// public override double Evaluate() { - return Expression.Evaluate(this.Left) * Expression.Evaluate(this.Right); + return ExpressionTree.Evaluate(this.Left) * ExpressionTree.Evaluate(this.Right); } } } diff --git a/SpreadsheetEnginge/Node.cs b/SpreadsheetEnginge/Node.cs index c702ccb..51f75d0 100644 --- a/SpreadsheetEnginge/Node.cs +++ b/SpreadsheetEnginge/Node.cs @@ -4,12 +4,6 @@ namespace SpreadsheetEngine { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Text; - using System.Threading.Tasks; - /// /// abstract node for expression tree. /// @@ -36,8 +30,8 @@ public abstract class Node public bool IsOperand { get; set; } /// - /// Gets or sets a value indicating whether if node contains a parenthesis. + /// Gets or sets a value indicating whether node is an openfaced "(" parenthesis. /// public bool IsParenthesis { get; set; } } -} \ No newline at end of file +} diff --git a/SpreadsheetEnginge/OperatorNode.cs b/SpreadsheetEnginge/OperatorNode.cs index 8065eda..3a2b470 100644 --- a/SpreadsheetEnginge/OperatorNode.cs +++ b/SpreadsheetEnginge/OperatorNode.cs @@ -1,48 +1,47 @@ -// CptS 321: Expression Tree Code Demo of how NOT to code your assignements -// Problems and sollutions of this code will be discussed in class -// Note that if you sumbit this code you will not get ANY points for the assignments +// +// Copyright (c) Stephen Graham - 011706998. All rights reserved. +// namespace SpreadsheetEngine { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + using SpreadsheetEngine; + + /// + /// Node that performs operations on other nodes. + /// public abstract class OperatorNode : Node { - - public OperatorNode(char c) - { - this.IsOperand = false; - this.IsParenthesis = false; - } - + /// + /// Initializes a new instance of the class. + /// Creates an operator node with a character argument. + /// + /// operator character. public OperatorNode(string c) { this.IsOperand = false; this.IsParenthesis = false; } + /// + /// Initializes a new instance of the class. + /// public OperatorNode() { this.IsOperand = false; this.IsParenthesis = false; } - public static bool ValidOperators(string c) - { - switch (c) - { - case "+": - case "-": - case "*": - case "/": - case "^": - case "(": - case ")": - return true; - } - - return false; - } - - public static bool ValidOperators(char c) + /// + /// Checks if input char is a valid operator. + /// + /// char of operator. + /// bool. + public static bool ValidOperator(char c) { switch (c) { @@ -59,9 +58,10 @@ public static bool ValidOperators(char c) return false; } - public string Operator { get; set; } - + /// + /// The operation to do to the nodes children, depending upon the character input. + /// + /// A double value of the operation. public abstract double Evaluate(); - } } \ No newline at end of file diff --git a/SpreadsheetEnginge/OperatorNodeFactory.cs b/SpreadsheetEnginge/OperatorNodeFactory.cs index 0fdeec1..36d6b1f 100644 --- a/SpreadsheetEnginge/OperatorNodeFactory.cs +++ b/SpreadsheetEnginge/OperatorNodeFactory.cs @@ -1,22 +1,30 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +// +// Copyright (c) Stephen Graham - 011706998. All rights reserved. +// namespace SpreadsheetEngine { + using System; + + /// + /// Creates different operatornodes based on the input operator string. + /// internal class OperatorNodeFactory { - public static OperatorNode CreateOperatorNode(char op) + /// + /// Creates approriate operator nodes based on char input. + /// + /// char of operator. + /// a node inheriting OperatorNode. + public static OperatorNode CreateOperatorNode(char oper) { - switch (op) + switch (oper) { case '+': AdditionNode add = new AdditionNode(); return add; case '-': - SubractionNode sub = new SubractionNode(); + SubtractionNode sub = new SubtractionNode(); return sub; case '*': MultiplicationNode mul = new MultiplicationNode(); diff --git a/SpreadsheetEnginge/ParenthesisNode.cs b/SpreadsheetEnginge/ParenthesisNode.cs index b1c8ad2..e83590a 100644 --- a/SpreadsheetEnginge/ParenthesisNode.cs +++ b/SpreadsheetEnginge/ParenthesisNode.cs @@ -1,18 +1,24 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +// +// Copyright (c) Stephen Graham - 011706998. All rights reserved. +// namespace SpreadsheetEngine { - class ParenthesisNode : OperatorNode + /// + /// Parenthesis operator node. + /// Only openfaced parenthesis "(" create nodes. + /// + internal class ParenthesisNode : OperatorNode { + /// + /// Initializes a new instance of the class. + /// public ParenthesisNode() { this.IsParenthesis = true; } + /// public override double Evaluate() { return 0; diff --git a/SpreadsheetEnginge/SpreadsheetEngine.csproj b/SpreadsheetEnginge/SpreadsheetEngine.csproj index 30ca4d7..0c520bd 100644 --- a/SpreadsheetEnginge/SpreadsheetEngine.csproj +++ b/SpreadsheetEnginge/SpreadsheetEngine.csproj @@ -56,7 +56,7 @@ - + diff --git a/SpreadsheetEnginge/SubractionNode.cs b/SpreadsheetEnginge/SubractionNode.cs deleted file mode 100644 index 5bce8f8..0000000 --- a/SpreadsheetEnginge/SubractionNode.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SpreadsheetEngine -{ - class SubractionNode : OperatorNode - { - public SubractionNode() - { - this.Precidence = 1; - } - - public override double Evaluate() - { - return Expression.Evaluate(this.Left) - Expression.Evaluate(this.Right); - } - } -} diff --git a/SpreadsheetEnginge/SubtractionNode.cs b/SpreadsheetEnginge/SubtractionNode.cs new file mode 100644 index 0000000..71d7052 --- /dev/null +++ b/SpreadsheetEnginge/SubtractionNode.cs @@ -0,0 +1,26 @@ +// +// Copyright (c) Stephen Graham - 011706998. All rights reserved. +// + +namespace SpreadsheetEngine +{ + /// + /// Subraction operator node. + /// + internal class SubtractionNode : OperatorNode + { + /// + /// Initializes a new instance of the class. + /// + public SubtractionNode() + { + this.Precidence = 1; + } + + /// + public override double Evaluate() + { + return ExpressionTree.Evaluate(this.Left) - ExpressionTree.Evaluate(this.Right); + } + } +} diff --git a/SpreadsheetEnginge/VariableNode.cs b/SpreadsheetEnginge/VariableNode.cs index 266eb5b..381189f 100644 --- a/SpreadsheetEnginge/VariableNode.cs +++ b/SpreadsheetEnginge/VariableNode.cs @@ -9,20 +9,22 @@ namespace SpreadsheetEngine using System.Linq; using System.Text; using System.Threading.Tasks; + using SpreadsheetEngine; /// - /// Node containing a variable value. + /// Variable node with variable name and value. /// public class VariableNode : Node { /// /// Initializes a new instance of the class. /// - /// name of the variable. + /// string of the name for the variable. public VariableNode(string name) { this.Name = name; this.Precidence = 0; + this.IsOperand = true; } /// @@ -31,10 +33,11 @@ public VariableNode(string name) public VariableNode() { this.Precidence = 0; + this.IsOperand = true; } /// - /// Gets or sets the name of the Variable Node. + /// Gets or sets the name of the VariableNode. /// public string Name { get; set; } }