예제 #1
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;
                }
            }
        }
        /*************************************************************
        * 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"));
        }
예제 #3
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);
            }
        }
예제 #4
0
파일: Spreadsheet.cs 프로젝트: sl8rw/CS321
 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)
         {
         }
     }
 }
예제 #5
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;
                    }
                }
            }
        }
예제 #6
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"));
        }
예제 #7
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);
            }
        }
예제 #8
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();
        }