Esempio n. 1
0
        private string solver(string equation)
        {
            ExpTree mytree = new ExpTree(equation);

            findCells(mytree);
            return(mytree.Eval().ToString());
        }
Esempio n. 2
0
 private string CalculateValue(string text, SpreadsheetCell senderCell)
 {
     text = text.Substring(1);                                                          //removes the first character of the string, which is =
     if (text.Length > 1)                                                               //if there are variables to replace, they will be at least 2 chars
     {
         MatchCollection           splitOperands   = Regex.Matches(text, @"\w+\.?\d*"); //temporary way to get all the variables.
         HashSet <SpreadsheetCell> referencedCells = new HashSet <SpreadsheetCell>();
         foreach (Match mat in splitOperands)
         {
             if (!Regex.Match(mat.Value, @"^\d+").Success)     // if the match starts with a number then its not a coordinate and we dont have to retrieve a value.
             {
                 SpreadsheetCell cell = GetCell(mat.Value) as SpreadsheetCell;
                 cell.ValueChanged += senderCell.OnValueChanged;
                 senderCell.AddReferenceToCell(cell);        //tell the sender cell what its referencing. Hashsets can only have unique values, so adding something that is already here will do nothing.
                 referencedCells.Add(cell);                  //keep track of which cells this specific expression looks for.
                 text = text.Replace(mat.Value, cell.Value); //replaces that substring in the text with that cell's value.
             }
         }
         referencedCells.SymmetricExceptWith(senderCell.ReferencedCells); //removes all the cell references that are the same.
         foreach (SpreadsheetCell cell in referencedCells)                // all the cells that were referenced previously but are no longer being referenced.
         {
             cell.ValueChanged -= senderCell.OnValueChanged;              // unsubsribes from the cell that is no longer being referenced.
             senderCell.RemoveReferenceToCell(cell);
         }
         ExpTree tree = new ExpTree(text);
         text = tree.Eval().ToString();
     }
     return(text);
 }
Esempio n. 3
0
        public void Menu()
        {
            int    flag             = 0;
            string expressionString = "(A1-12-C1)"; //now having error in parentheses
            string varName;
            string varValue;
            double numValue;

            newExpressionTree = new ExpTree(expressionString);

            while (flag != 1) //1 causes problems
            {
                Console.WriteLine("_________________MENU_________________");
                Console.WriteLine("The expression entered is: " + expressionString);

                /*Console.WriteLine("Would you like to update this expression? Enter y for yes and n for no \n");
                 * char userInput = Console.ReadKey().KeyChar; //this can cause errors in program testing, just for my own testing purposes
                 * if (userInput == 'y')
                 * {
                 *  Console.WriteLine("Please input your new expression with NO whitespaces: \n");
                 *  expressionString = Console.ReadLine();
                 *
                 * }*/

                Console.WriteLine("(1): Update Expression");
                Console.WriteLine("(2): Update the value");
                Console.WriteLine("(3): Evaluate the tree");
                Console.WriteLine("(4): GoodBye");
                string userInput = Console.ReadLine().ToString();
                Console.WriteLine("You entered option {0}", userInput);
                switch (userInput)
                {
                case "1":
                    Console.WriteLine("Please enter a new expression: ");
                    expressionString  = Console.ReadLine();
                    newExpressionTree = new ExpTree(expressionString);
                    break;

                case "2":
                    Console.WriteLine("Enter a variable name: ");
                    varName = Console.ReadLine();
                    Console.WriteLine("Now please enter a value of that variable: ");
                    varValue = Console.ReadLine();
                    numValue = Convert.ToDouble(varValue);                                           //need to make the value a double

                    Console.WriteLine("Variable Name: {0}\nVariable Value: {1}", varName, numValue); //updated by SHW for readability

                    newExpressionTree.SetVar(varName, numValue);                                     //takes string and double, makes brand new exp tree
                    break;

                case "3":
                    Console.WriteLine("The result is: {0}", newExpressionTree.Eval());
                    break;

                case "4":
                    flag = 1;     //exit flag
                    break;
                }
            }
        }
Esempio n. 4
0
 private void findCells(ExpTree tree)
 {
     foreach (var item in tree.variables.ToList())
     {
         tree.variables[item.Key] = float.Parse(cellLocation(item.Key).Value);
         tree.setVar(item.Key, float.Parse(cellLocation(item.Key).Value));
     }
 }
Esempio n. 5
0
 public string Calculator(string newval, Cell hold)
 {
     if (newval == string.Empty)
     {
         // Clear values and unassign cells if current cell reset
         foreach (string key in hold.sharevals.Keys)
         {
             hold.sharevals[key].PropertyChanged -= hold.Val_PropertyChanged;
         }
         hold.sharevals.Clear();
         return("");
     }
     else if (newval[0] != '=')
     {
         // Clear values and unassign cells if current cell reset
         foreach (string key in hold.sharevals.Keys)
         {
             hold.sharevals[key].PropertyChanged -= hold.Val_PropertyChanged;
         }
         hold.sharevals.Clear();
         return(newval);
     }
     // use getcell to find cell value if set equal to one
     else
     {
         // Added expression tree implementation for '=' condition
         ExpTree         ret     = new ExpTree(newval);
         string          grab    = "";
         string          Letters = "[a-zA-Z]+[\\d]*";
         string          Ops     = "[+\\-/*()\\^]";
         Regex           Val     = new Regex(Letters);
         MatchCollection Matches = Val.Matches(newval);
         foreach (Match match in Matches)
         {
             grab = getCell(match.Value, hold);
             double set = 0.0;
             if (double.TryParse(grab, out set))
             {
                 ret.setVar(match.Value, set);
             }
             else
             {
                 if (new Regex(Ops).IsMatch(newval) && grab != string.Empty)
                 {
                     return("#REF");
                 }
                 else
                 {
                     return(grab);
                 }
             }
         }
         return(ret.Evaluate().ToString());
     }
 }
Esempio n. 6
0
        static int Main(string[] Args)
        {
            Dictionary <string, double> _dict = new Dictionary <string, double>();
            // Set start at values, basically 0+0+0 until A1, B1, and/or C1 declared
            ExpTree Exp    = new ExpTree("A1+B1+C1");
            int     choice = 0;
            double  result;
            string  choice1 = string.Empty;

            // Loops indefinitely, ends if selection 4 is chosen
            while (true)
            {
                // Menu portion
                Console.WriteLine("1) Enter Expression");
                Console.WriteLine("2) Set Variable Value");
                Console.WriteLine("3) Evaluate Expression");
                Console.WriteLine("4) Quit");
                Console.Write("Enter Choice: ");
                choice1 = Console.ReadLine();
                Int32.TryParse(choice1, out choice);
                // Actions for various choices
                if (choice == 1)
                {
                    Console.Write("Enter New Expression: ");
                    Exp._Evalstring = Console.ReadLine();
                }
                else if (choice == 2)
                {
                    // Request Variable name and new value from user
                    Console.Write("Enter Variable Name: ");
                    string replace = Console.ReadLine();
                    Console.Write("Enter New Value: ");
                    string with = Console.ReadLine();
                    // Add values to dictionary
                    double.TryParse(with, out result);
                    Exp.setVar(replace, result);
                    // Replace instances of variable with newly established value
                }
                else if (choice == 3)
                {
                    Console.WriteLine(Exp._Evalstring + " = " + Exp.Evaluate());
                }
                else if (choice == 4)
                {
                    return(0);
                }
                // If input isnt 1-4 tell them invalid and ask again
                else
                {
                    Console.WriteLine("Invalid Input");
                }
            }
        }
        /*************************************************************
        * Function: OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        * Date Created: Feb 8, 2017
        * Date Last Modified: Feb 9, 2017
        * Description: OnPropertyChanged
        * Return: void
        *************************************************************/
        public void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Text")
            {
                createACell tmpCell = sender as createACell;
                RemoveDep(tmpCell.Name);

                if (tmpCell.Text != "" && tmpCell.Text[0] == '=')
                {
                    ExpTree exp = new ExpTree(tmpCell.Text.Substring(1));
                    MakeDep(tmpCell.Name, exp.GetAllVariables());
                }
                Eval(sender as Cell);
            }
        }
Esempio n. 8
0
 private void DefineVars(ExpTree newTree)
 {
     foreach (var name in newTree.varNameList)
     {
         var col      = name[0] - 'A';
         var row      = Convert.ToInt32(name.Substring(1)) - 1;
         var tempCell = GetCell(col, row);
         try
         {
             newTree.SetVar(name, Convert.ToDouble(tempCell.Value));
         }
         catch (FormatException)
         {
         }
     }
 }
        /*************************************************************
        * Function: setExp(createACell m_Cell, Cell cell)
        * Date Created: Feb 8, 2017
        * Date Last Modified: Feb 9, 2017
        * Description: set value to exp
        * Return: void
        *************************************************************/
        private void setExp(createACell m_Cell, Cell cell)
        {
            ExpTree exptree = new ExpTree(m_Cell.Text.Substring(1));

            string[] variables = exptree.GetAllVariables();
            foreach (string variableName in variables)
            {
                Cell   variableCell = GetCell(variableName);
                double value;

                if (string.IsNullOrEmpty(variableCell.Value))
                {
                    exptree.SetVar(variableCell.Name, 0);
                }

                else if (!double.TryParse(variableCell.Value, out value))
                {
                    exptree.SetVar(variableName, 0);
                }

                else
                {
                    exptree.SetVar(variableName, value);
                }
            }

            //old code from hw4
            //string letter = m_Cell.Text.Substring(1);
            //string number = letter.Substring(1);
            //string lettersAZ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            //int col = 0, row = int.Parse(number) - 1;
            //for (int i = 0; i < 26; i++)
            //{
            //    if (lettersAZ[i] == letter[0])
            //    {
            //        col = i;
            //        break;
            //    }
            //}
            //m_Cell.SetValue(GetCell(row, col).Value.ToString());

            m_Cell.SetValue(exptree.Eval().ToString());
            CellPropertyChanged(cell, new PropertyChangedEventArgs("Value"));
        }
Esempio n. 10
0
        // sets a cell's value in the ExpTree's variable dictionary
        private void SetCellVariable(ExpTree userExpTree, string varName)
        {
            // get the cell based on the varName
            Cell relevantCell = GetCell(varName);

            double value;

            // check if the cell's value is a double
            if (double.TryParse(relevantCell.Value, out value))
            {
                // if it's a double, set its variable to that double value
                userExpTree.SetVar(varName, value);
            }
            else
            {
                // otherwise set its variable to 0.0
                userExpTree.SetVar(varName, 0.0);
            }
        }
Esempio n. 11
0
        private void getCellValue(Cell c)
        {
            //c = (cell)sender
            if (c.setText.Length == 0)
            {
                c.Value = "";
            }
            else if (!c.setText.StartsWith("=")) //no formula
            {
                c.Value = c.setText;
            }
            else // formula
            {
                if (c.setText.Length > 1)
                {
                    try
                    {
                        string   equation = c.setText.Substring(1);
                        ExpTree  xp       = new ExpTree(equation);
                        string[] cref     = xp.getVariables();

                        foreach (string name in cref)
                        {
                            double val = getCorrCellVal(name);
                            xp.SetVar(name, val);

                            Cell key = getCorrCell(name);
                            if (!dep.ContainsKey(key)) //add dependency
                            {
                                dep.Add(key, new HashSet <Cell>());
                            }
                            dep[key].Add(c);
                        }
                        c.Value = xp.Eval().ToString();
                    }
                    catch
                    {
                        c.Value = "#REF!";
                        throw;
                    }
                }
            }
        }
Esempio n. 12
0
        static void Main(string[] args)
        {
            ExpTree mytree = new ExpTree("22 * 34 * (36 + (37 - 17) * 23)"); //371008 should be the evaluated result

            string menu = "1";
            string words;
            int    numbers;
            double result;

            while (menu != "4")
            {
                Console.WriteLine("Menu (current expression=\"{0}\")", mytree.rregex);
                Console.WriteLine("   1 = Enter a new expression");
                Console.WriteLine("   2 = Set a variable value");
                Console.WriteLine("   3 = Evaluate tree");
                Console.WriteLine("   4 = Quit");

                menu = Console.ReadLine();
                if (menu == "1")
                {
                    Console.Write("Enter new expression: ");
                    words         = Console.ReadLine();
                    mytree.rregex = words;
                    mytree        = new ExpTree(words);
                }
                else if (menu == "2")
                {
                    Console.Write("Enter variable name: ");
                    words = Console.ReadLine();
                    Console.Write("Enter variable value: ");
                    numbers = Convert.ToInt32(Console.ReadLine());
                    mytree.setVar(words, numbers);
                }
                else if (menu == "3")
                {
                    result = mytree.Eval();
                    Console.WriteLine("{0}", result);
                }
            }
            Console.WriteLine("Done");
        }
Esempio n. 13
0
        static void Main(string[] args)
        {
            ExpTree mytree = new ExpTree("A1-12-C1");

            int    menu = 1;
            string words;
            int    numbers;
            double result;

            while (menu != 4)
            {
                Console.WriteLine("current expression=\"{0}\")", mytree.rregex);
                Console.WriteLine("   1 = Enter a new expression");
                Console.WriteLine("   2 = Set a variable value");
                Console.WriteLine("   3 = Evaluate tree");
                Console.WriteLine("   4 = Quit");

                menu = Convert.ToInt32(Console.ReadLine());
                if (menu == 1)
                {
                    Console.Write("Enter new expression: ");
                    words         = Console.ReadLine();
                    mytree.rregex = words;
                    mytree        = new ExpTree(words);
                }
                else if (menu == 2)
                {
                    Console.Write("Enter variable name: ");
                    words = Console.ReadLine();
                    Console.Write("Enter variable value: ");
                    numbers = Convert.ToInt32(Console.ReadLine());
                    mytree.setVar(words, numbers);
                }
                else if (menu == 3)
                {
                    result = mytree.Eval();
                    Console.WriteLine("{0}", result);
                }
            }
            Console.WriteLine("Done");
        }
Esempio n. 14
0
        // overloaded UpdateCell, takes a cell as the parameter
        private void UpdateCell(Cell cellToUpdate)
        {
            // remove old dependencies
            RemoveDependencies(cellToUpdate);

            // first check if the cell is empty
            // i.e. the user deleted the text from the cell
            if (string.IsNullOrEmpty(cellToUpdate.Text))
            {
                cellToUpdate.Value = "";
            }
            // if the text doesn't begin with an =
            else if (cellToUpdate.Text[0] != '=')
            {
                double cellValue;

                // if the cell contains a double
                if (double.TryParse(cellToUpdate.Text, out cellValue))
                {
                    // build the ExpTree to set the cell's variable
                    ExpTree userExpTree = new ExpTree(cellToUpdate.Text);
                    cellValue = userExpTree.Eval();
                    userExpTree.SetVar(cellToUpdate.Name, cellValue);

                    // update the value to the double
                    cellToUpdate.Value = cellValue.ToString();
                }
                else
                {
                    // otherwise the value is just set to the text
                    cellToUpdate.Value = cellToUpdate.Text;
                }
            }
            // need to evaluate an expression here
            else
            {
                // parse the text to get the expression
                string exp = cellToUpdate.Text.Substring(1);

                // build an ExpTree, eval to add variables
                ExpTree userExpTree = new ExpTree(exp);
                userExpTree.Eval();

                // get the variable names
                string[] varNames = userExpTree.GetVarNames();

                // loop through each variable name in the array
                foreach (string variable in varNames)
                {
                    // get the cell and add its value to the dictionary
                    double value        = 0.0;
                    Cell   relevantCell = GetCell(variable);

                    // try to parse out the double
                    double.TryParse(relevantCell.Value, out value);

                    // set the variable
                    userExpTree.SetVar(variable, value);
                }

                // set the value to the computed value of the ExpTree
                cellToUpdate.Value = userExpTree.Eval().ToString();

                // add the dependencies
                AddDependencies(cellToUpdate, varNames);
            }

            // if there are cells that depend on the one we just updated
            if (m_dependencies.ContainsKey(cellToUpdate))
            {
                // update all dependent cells
                UpdateDependencies(cellToUpdate);
            }

            // and notify subscribers that the cell property changed
            // need to pass the sender which is the cell
            // passing the this reference would pass the spreadsheet
            CellPropertyChanged(cellToUpdate, new PropertyChangedEventArgs("CellChanged"));
        }
Esempio n. 15
0
        // overloaded UpdateCell, takes a cell as the parameter
        private void UpdateCell(Cell cellToUpdate)
        {
            // remove old dependencies
            RemoveDependencies(cellToUpdate);

            // first check if the cell is empty
            // i.e. the user deleted the text from the cell
            if (string.IsNullOrEmpty(cellToUpdate.Text))
            {
                cellToUpdate.Value = "";
            }
            // if the text doesn't begin with an =
            else if (cellToUpdate.Text[0] != '=')
            {
                double cellValue;

                // if the cell contains a double
                if (double.TryParse(cellToUpdate.Text, out cellValue))
                {
                    // build the ExpTree to set the cell's variable
                    ExpTree userExpTree = new ExpTree(cellToUpdate.Text);
                    cellValue = userExpTree.Eval();
                    userExpTree.SetVar(cellToUpdate.Name, cellValue);

                    // update the value to the double
                    cellToUpdate.Value = cellValue.ToString();
                }
                else
                {
                    // otherwise the value is just set to the text
                    cellToUpdate.Value = cellToUpdate.Text;
                }
            }
            // need to evaluate an expression here
            else
            {
                // flag to check for errors
                bool errors = false;

                // parse the text to get the expression
                string exp = cellToUpdate.Text.Substring(1);

                // build an ExpTree, eval to add variables
                ExpTree userExpTree = new ExpTree(exp);
                userExpTree.Eval();

                // get the variable names
                string[] varNames = userExpTree.GetVarNames();

                // loop through each variable name in the array
                foreach (string variable in varNames)
                {
                    // get the cell and add its value to the dictionary
                    double value        = 0.0;
                    Cell   relevantCell = GetCell(variable);

                    // check for valid cells
                    // CASE ONE: BAD REFERENCE
                    if (relevantCell == null)
                    {
                        // display that the cell has a bad reference and notify subscribers
                        cellToUpdate.Value = "!(bad reference)";
                        CellPropertyChanged(cellToUpdate, new PropertyChangedEventArgs("CellChanged"));

                        // set the error flag to true
                        errors = true;
                    }
                    // CASE TWO: SELF-REFERENCE
                    else if (cellToUpdate.Name == variable)
                    {
                        // display that the cell has a self-reference and notify subscribers
                        cellToUpdate.Value = "!(self reference)";
                        CellPropertyChanged(cellToUpdate, new PropertyChangedEventArgs("CellChanged"));

                        // set the error flag to true
                        errors = true;
                    }

                    // if there's an error, get out of the function
                    if (errors == true)
                    {
                        // if there are cells that depend on the one we just updated
                        if (m_dependencies.ContainsKey(cellToUpdate))
                        {
                            // update all dependent cells
                            UpdateDependencies(cellToUpdate);
                        }

                        return;
                    }

                    // try to parse out the double
                    double.TryParse(relevantCell.Value, out value);

                    // set the variable
                    userExpTree.SetVar(variable, value);

                    // add the cell to the HashSet to check for circular references
                    this.visitedCells.Add(relevantCell);
                }

                // set the value to the computed value of the ExpTree
                cellToUpdate.Value = userExpTree.Eval().ToString();

                // add the dependencies
                AddDependencies(cellToUpdate, varNames);

                // check for circular references
                if (CheckForCircularReferences(cellToUpdate))
                {
                    // display that the cell has a circular-reference and notify subscribers
                    cellToUpdate.Value = "!(circular reference)";
                    CellPropertyChanged(cellToUpdate, new PropertyChangedEventArgs("CellChanged"));

                    // set the error flag to true
                    errors = true;
                }

                // if there's an error, get out of the function
                if (errors == true)
                {
                    return;
                }
            }

            // if there are cells that depend on the one we just updated
            if (m_dependencies.ContainsKey(cellToUpdate))
            {
                // update all dependent cells
                UpdateDependencies(cellToUpdate);
            }

            // and notify subscribers that the cell property changed
            // need to pass the sender which is the cell
            // passing the this reference would pass the spreadsheet
            CellPropertyChanged(cellToUpdate, new PropertyChangedEventArgs("CellChanged"));

            // clear the visited cells HashSet at a successful cell change
            this.visitedCells.Clear();
        }
Esempio n. 16
0
        private string userInput;                                                           // Used for menu interface

        public ExpTree(string expression)
        {
            int  operandBegin = 0;      // Index of where the first character of the operand exists
            bool exit         = false;  // Used for logic with paranthesis and how they are placed onto appropriate stack
            bool paranthesis  = false;  // If true, we know that the last paranthesis was placed onto stack and we do not need to create another operand for current operator

            // Iterate through length of given expression
            for (int i = 0; i < expression.Length; i++)
            {
                char currentChar = expression[i];
                // If looking at an operator
                if (currentChar == '+' || currentChar == '-' || currentChar == '*' || currentChar == '/')
                {
                    // Create an appropriate OpNode
                    OpNode newOp = new OpNode(currentChar.ToString());

                    // Last thing we looked at was not ')'
                    if (paranthesis == false)
                    {
                        //  Create an operand node with last operand and place onto stack
                        Node newNode = determineNode(expression, operandBegin, i);
                        operandStack.Push(newNode);
                    }
                    // We know that there is no 'new' operand to be placed on stack, sub-tree contained in () is already placed onto operand stack
                    else
                    {
                        // Reset the paranthesis flag
                        paranthesis = false;
                    }
                    // Next operand should begin immediately after the operator, note this would be different if urnary operators were included
                    operandBegin = i + 1;

                    // Determine what to do with current and previous operators
                    if (operatorStack.Count > 0)
                    {
                        // Need to peak at top of operand stack, if higher precedence need to push current operand down
                        if (operatorStack.Peek().Precedence < newOp.Precedence)
                        {
                            operatorStack.Push(newOp);
                        }
                        // If lower precedence, need to pop and form node
                        else
                        {
                            OpNode newParent = operatorStack.Pop();
                            newParent.RightChild = operandStack.Pop();
                            newParent.LeftChild  = operandStack.Pop();
                            operandStack.Push(newParent);

                            operatorStack.Push(newOp);
                        }
                    }

                    else
                    {
                        // If the operator stack is empty, it is essentially a sentinal like the hint paper was describing
                        operatorStack.Push(newOp);
                    }
                }
                else if (currentChar == '(')
                {
                    // Need to form new tree
                    ExpTree newTree = new ExpTree(expression.Substring(i + 1));

                    //TEST
                    i           = expression.IndexOf(')', i + 1);
                    paranthesis = true;

                    operandStack.Push(newTree.root);
                }
                else if (currentChar == ')')
                {
                    // End new tree, pop back out
                    Node newNode = determineNode(expression, operandBegin, i);
                    operandStack.Push(newNode);
                    root = formTree(operandStack, operatorStack);
                    exit = true;
                    break;
                }
            }

            // Since we are only using binary oprators, the operand stack must be even when expression is completely evaluated
            if (operandStack.Count > 0 & (operandStack.Count % 2 != 0) & exit == false)
            {
                Node newNode = determineNode(expression, operandBegin, expression.Length);
                operandStack.Push(newNode);
            }
            // Provide an entry point for outside world to access
            root = formTree(operandStack, operatorStack);
        }
Esempio n. 17
0
        private void Spreadsheet_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if ("Text" == e.PropertyName)               //checks if Cell.Text property was changed
            {
                string oldValue = ((Cell)sender).Value; //make a copy of the value of the old string for undo methods
                ICmd   temp     = new RestoreText((Cell)sender, oldValue);
                AddUndo(temp);
                if (((Cell)sender).Text.IndexOf('=') == 0) //must evaluate if it's a formula
                {
                    //remove cell from every hashset in dependency table to update the dependency table after formula evaluation
                    foreach (KeyValuePair <Cell, HashSet <Cell> > p in dependencies)
                    {
                        dependencies[p.Key].Remove((Cell)sender);
                    }

                    string   formula   = ((Cell)sender).Text.Replace("=", "");
                    var      tree      = new ExpTree(formula);                                                   //put the formula in tree for evaluation
                    string[] variables = tree.GetVars();                                                         //get the variables from the tree
                    if (checkValidFormulaVariables(variables) && !checkSelfReference(((Cell)sender), variables)) //check if variables are in valid format
                    {
                        foreach (string s in variables)
                        {
                            double value = getCorrespondingCellValue(s); //get the individual variable value
                            tree.SetVar(s, value);                       //set the variable so the tree can evaluate the expression
                            updateDependencyTable((Cell)sender, s);
                        }
                        double finalValue = tree.Eval(); //returns the final result of formula evaluation
                        ((Cell)sender).Value = finalValue.ToString();
                    }
                    else if (!checkValidFormulaVariables(variables)) //variables not in valid format
                    {
                        tree.ClearVariables();                       //delete bad variables
                        ((Cell)sender).Text = "!(invalid entry)";
                    }
                    else
                    {
                        tree.ClearVariables();
                        ((Cell)sender).Text = "!(self reference)";
                    }
                }
                else //just a constant value or some string was entered
                {
                    //check if any cells depend on the cell where value was changed and update them
                    if (dependencies.ContainsKey((Cell)sender) && dependencies[(Cell)sender].Count > 0)
                    {
                        foreach (Cell cell in dependencies[(Cell)sender])
                        {
                            //Re-evaluate the formulas of each cell depending on the changed cell
                            string   formula = cell.Text.Replace("=", "");
                            var      tree    = new ExpTree(formula);
                            string[] vars    = tree.GetVars();
                            if (checkValidFormulaVariables(vars)) //check if variables are in valid format
                            {
                                foreach (string v in vars)
                                {
                                    Cell   check    = getCorrespondingCell(v);
                                    double varValue = 0.0;
                                    if (check == ((Cell)sender))                            //check if the variable is the cell being changed
                                    {
                                        double.TryParse(((Cell)sender).Text, out varValue); //set value of that variable to the newly changed value
                                    }
                                    else
                                    {
                                        varValue = getCorrespondingCellValue(v);
                                    }
                                    tree.SetVar(v, varValue);
                                }
                                double finalValue = tree.Eval(); //returns the final result of formula evaluation
                                cell.Value = finalValue.ToString();
                            }
                            else
                            {
                                cell.Text = "!(invalid entry)";
                            }
                        }
                    }
                    ((Cell)sender).Value = ((Cell)sender).Text; //set the value of the cell
                }
            }

            if (CellPropertyChanged != null) //does the event have subscribers?
            {
                CellPropertyChanged(sender, e);
            }
        }
Esempio n. 18
0
        public void Cells_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            SpreadsheetCell spreadsheetCell = sender as SpreadsheetCell; //Sender as a spreadsheet cell

            switch (e.PropertyName)                                      //switch on the property changed
            {
            case ("Text"):                                               //if text has been changed
                if (spreadsheetCell.Text == string.Empty)
                {
                    spreadsheetCell.Value = string.Empty;
                    NotifyCellPropertyChanged(spreadsheetCell);
                    //spreadsheetCell.Sendupdate();
                }

                else if (spreadsheetCell.Text[0] == '=')
                {
                    spreadsheetCell.Value = spreadsheetCell.Text;
                    NotifyCellPropertyChanged(spreadsheetCell);
                    spreadsheetCell.Sendupdate();
                }
                else if (spreadsheetCell.Text[0] != '=' && spreadsheetCell.Value == string.Empty)
                {
                    spreadsheetCell.Value = spreadsheetCell.Text;
                    NotifyCellPropertyChanged(spreadsheetCell);
                    spreadsheetCell.Sendupdate();
                }
                else if (spreadsheetCell.Text[0] != '=' && spreadsheetCell.Value[0] != '=')
                {
                    spreadsheetCell.Value = spreadsheetCell.Text;
                    NotifyCellPropertyChanged(spreadsheetCell);
                    spreadsheetCell.Sendupdate();
                }

                break;

            case ("Value"):
                try
                {
                    if (spreadsheetCell.Value != string.Empty)
                    {
                        if (spreadsheetCell.Value[0] == '=')
                        {
                            if (char.IsLetter(spreadsheetCell.Value[1]) && spreadsheetCell.Value.Length <= 4 && spreadsheetCell.Value.Length >= 2)
                            {
                                string          varcol         = spreadsheetCell.Value[1].ToString();
                                string          varrow         = spreadsheetCell.Value.Substring(2);
                                SpreadsheetCell referencedcell = getcellat(varcol, varrow);
                                if (spreadsheetCell.Text != referencedcell.Text)
                                {
                                    spreadsheetCell.Text = referencedcell.Text;
                                }
                                referencedcell.Referencesme(spreadsheetCell);
                            }
                            else if (spreadsheetCell.Value.Length >= 2)     //starts with = and is within the length of a valid function
                            {
                                ExpTree expTree = new ExpTree(spreadsheetCell.Value.Substring(1));
                                expTree.Eval();
                                string varcol;
                                string varrow;
                                double vardata;
                                Dictionary <string, double> vardic = new Dictionary <string, double>(expTree.variables);
                                foreach (string key in vardic.Keys)
                                {
                                    varcol = key.Substring(0, 1);
                                    varrow = key.Substring(1);
                                    SpreadsheetCell referencedcell = getcellat(varcol, varrow);
                                    if (referencedcell == spreadsheetCell)
                                    {
                                        //ToDo-- If self is in the equation
                                        vardata = 0;
                                    }
                                    else
                                    {
                                        Double.TryParse(referencedcell.Text, out vardata);
                                    }

                                    referencedcell.Referencesme(spreadsheetCell);
                                    expTree.SetVAr(key, vardata);
                                }
                                string eval = expTree.Eval().ToString();
                                if (spreadsheetCell.Text != eval)
                                {
                                    spreadsheetCell.Text = eval;
                                }
                            }
                        }
                    }
                }
                catch
                {
                    spreadsheetCell.Text = "#ERROR";
                }
                break;
            }
        }
Esempio n. 19
0
        private void Spreadsheet_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            //from crandall

            rmDep((Cell)sender);
            if (e.PropertyName == "Text")
            {
                changedCells.Add((Cell)sender);

                if (!((Cell)sender).Text.StartsWith("="))
                {
                    ((Cell)sender).Value = ((Cell)sender).Text;
                }
                else
                {
                    var expression = ((Cell)sender).Text;  //this will get the expression
                    try
                    {
                        var     subExp       = expression.Substring(1);
                        ExpTree ssExpression = new ExpTree(subExp);
                        DefineVars(ssExpression);
                        ((Cell)sender).Value = ssExpression.Eval().ToString();
                        if (((Cell)sender).Value == "NaN")
                        {
                            ((Cell)sender).Value = expression;
                            ((Cell)sender).Value = GetCell(expression.Substring(1)).Value;
                            CellPropertyChanged.Invoke(sender,
                                                       new PropertyChangedEventArgs("Value"));
                        }

                        addDep((Cell)sender, ssExpression.varNameList);
                    }
                    catch

                    {
                        //we are concerned with #REF
                        try
                        {
                            var ssExpression = new ExpTree(((Cell)sender).Text.Substring(1).ToUpper());
                            ((Cell)sender).Value = "#REF";
                            CellPropertyChanged.Invoke(sender,
                                                       new PropertyChangedEventArgs("Value"));
                            addDep((Cell)sender, ssExpression.varNameList);
                        }
                        catch
                        {
                            //need to check if there is an = operator without any following
                            ((Cell)sender).Value = "#REF";
                            CellPropertyChanged.Invoke(sender,
                                                       new PropertyChangedEventArgs("Value"));
                        }

                        ((Cell)sender).Value = "#REF";
                        CellPropertyChanged.Invoke(sender,
                                                   new PropertyChangedEventArgs("Value"));
                    }
                }
            }

            if (cellDependency.ContainsKey((Cell)sender))
            {
                updateDep((Cell)sender);
            }
            CellPropertyChanged.Invoke(sender,
                                       new PropertyChangedEventArgs("Value"));
        }