public void TestEqualsWithNormalizer()
 {
     Formula a = new Formula("x1 + x2", VarToUpper, IsValid);
     Formula b = new Formula("X1 + X2");
     Assert.AreEqual(true, a.Equals(b));
     Assert.AreEqual(true, b.Equals(a));
 }
 public void TestEqualsBothNull()
 {
     Formula a = new Formula(null);
     Formula b = new Formula(null);
     Assert.AreEqual(true, a == b);
     Assert.AreEqual(true, b == a);
 }
Example #3
0
        /// <summary>
        /// If the formula parameter is null, throws an ArgumentNullException.
        ///
        /// Otherwise, if name is null or invalid, throws an InvalidNameException.
        ///
        /// Otherwise, if changing the contents of the named cell to be the formula would cause a
        /// circular dependency, throws a CircularException.  (No change is made to the spreadsheet.)
        ///
        /// Otherwise, the contents of the named cell becomes formula.  The method returns a
        /// Set consisting of name plus the names of all other cells whose value depends,
        /// directly or indirectly, on the named cell.
        ///
        /// For example, if name is A1, B1 contains A1*2, and C1 contains B1+A1, the
        /// set {A1, B1, C1} is returned.
        /// </summary>
        /// <param name="name">cellname</param>
        /// <param name="formula">content is formula</param>
        /// <returns></returns>
        protected override ISet <string> SetCellContents(string name, SpreadsheetUtilities.Formula formula)
        {
            // check check check
            //if (ReferenceEquals(formula, null)) { throw new ArgumentNullException(); }
            //if (name == null) { throw new InvalidNameException(); }
            //if (!IsValid(name)) { throw new InvalidNameException(); }

            // initialized result and tempDependent
            HashSet <string> result = new HashSet <string>();
            // store the name's Dependents in temporary hashset to prepare the circular dependency case
            HashSet <string> tempDependents = new HashSet <string>(DG.GetDependents(name));

            // this try-catch statement will check circular dependency
            try
            {
                // input the empty hashset for dependent.
                if (sheet.ContainsKey(name))
                {
                    DG.ReplaceDependents(name, new HashSet <string>());
                }
                // we have to return all veriables like set {A1, B1, C1} and store into DG
                foreach (String s in formula.GetVariables())
                {
                    DG.AddDependency(name, s);
                }
                //recalculate the cellname's contents
                result = new HashSet <string>(GetCellsToRecalculate(name));
            }
            catch (CircularException e)
            {
                //just keep tracking previous dependents..
                DG.ReplaceDependents(name, tempDependents);
                throw e;
            }

            // Now, set the sheet!
            if (sheet.ContainsKey(name))
            {
                sheet.Remove(name);     //make sure
                sheet[name] = new Cell(name, formula, lookup);
            }
            else
            {
                sheet.Add(name, new Cell(name, formula, lookup));
            }

            //update if the cell has a formula!
            foreach (String s in result)
            {
                if (sheet.ContainsKey(s) && sheet[s].getContent() is Formula)
                {
                    //For re-Evaluate
                    Cell c = new Cell(s, sheet[s].getContent(), lookup);
                    sheet.Remove(s);
                    sheet.Add(s, c);
                }// exception handle??
            }

            return(result);
        }
 public void TestNotEqualsBothNull()
 {
     Formula a = new Formula(null);
     Formula b = new Formula(null);
     Assert.AreEqual(false, a != b);
     Assert.AreEqual(false, b != a);
 }
Example #5
0
        /// <summary>
        /// Sets the cell contents with a Formula. Throws CircularException if a circular dependency is established.
        /// </summary>
        /// <param name="name">Name of the cell to set contents inside of</param>
        /// <param name="formula">Formula to place in cell</param>
        /// <returns>ISet<string> of all the cells that need to be updated</string></returns>
        protected override ISet <string> SetCellContents(string name, SpreadsheetUtilities.Formula formula)
        {
            IEnumerable <string> variables = formula.GetVariables();

            foreach (String variable in variables)
            {
                if (!IsValid(variable))
                {
                    throw new FormulaFormatException("Invalid cell name.");
                }
                cellDependency.AddDependency(Normalize(variable), name);
            }

            try
            {
                IEnumerable <string> cellsToRecalculate = GetCellsToRecalculate(name);
            }
            //Oops there's been a circular exception, restore the dependencies
            catch (CircularException)
            {
                foreach (String variable in variables)
                {
                    cellDependency.RemoveDependency(Normalize(variable), name);
                }

                //Now that the dependencies are restored, we can throw the exception out
                throw new CircularException();
            }

            //No exception, change the cell to the formula and evaluate the formula also
            //cells[name] = new Cell(formula, formula.Evaluate(s => (double)cells[s].value));
            cells[name] = new Cell(formula, formula.Evaluate(VariableLookup));

            return(new HashSet <string>(GetCellsToRecalculate(name)));
        }
Example #6
0
        public void TestMethod1()
        {
            //stractSpreadsheet sp = new Spreadsheet();

            Formula f = new Formula("2+2");
            
        }
 public void TestEqualsFromToString()
 {
     string expression = "x + 2";
     Formula a = new Formula(expression);
     Formula b = new Formula(a.ToString());
     Assert.AreEqual(true, a.Equals(b));
     Assert.AreEqual(true, b.Equals(a));
 }
 public void TestHashCodeTrue()
 {
     Formula a = new Formula("2 + X3");
     int hashCodeA = a.GetHashCode();
     Formula b = new Formula("2+X3");
     int hashCodeB = b.GetHashCode();
     Assert.AreEqual(hashCodeA, hashCodeB);
 }
Example #9
0
        public string SetContentsWithFormulaReturnString(AbstractSpreadsheet sheet, string name, Formula formula)
        {
            List<string> cell_names = new List<string>(sheet.SetCellContents(name, formula));
            string[] cell_array = cell_names.ToArray();
            string text = string.Join(",", cell_array);

            return text;
        }
Example #10
0
        static void Main(string[] args)
        {
            String lpPattern = @"\(";
            String rpPattern = @"\)";
            String opPattern = @"[\+\-*/]";
            String varPattern = @"[a-zA-Z_](?: [a-zA-Z_]|\d)*";
            //String doublePattern = @"(?: \d+\.\d* | \d*\.\d+ | \d+ ) (?: [eE][\+-]?\d+)?";
            String doublePattern = @"^[0-9\.]*$";
            String spacePattern = @"\s+";

            // Overall pattern
            String pattern = String.Format("({0}) | ({1}) | ({2}) | ({3}) | ({4}) | ({5})",
                                            lpPattern, rpPattern, opPattern, varPattern, doublePattern, spacePattern);

            Formula f = new Formula("2.0 + x7 + b6+9- c");
               String s = f.GetVariables().ToList().ToString();
            Debug.WriteLine(s);
        }
Example #11
0
 public void Test33()
 {
     Formula f = new Formula("4-3*1/a4");
     Assert.IsTrue(f.Evaluate(s => 0) is FormulaError);
 }
Example #12
0
 /// <summary>
 /// Creates a cell that has a formula.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="formula"></param>
 public Cell(String name, Formula formula)
 {
     this.name = name;
     this.formula = formula;
     this.isFormula = true;
 }
Example #13
0
        /// <summary>
        /// If content is null, throws an ArgumentNullException.
        /// 
        /// Otherwise, if name is null or invalid, throws an InvalidNameException.
        /// 
        /// Otherwise, if content parses as a double, the contents of the named
        /// cell becomes that double.
        /// 
        /// Otherwise, if content begins with the character '=', an attempt is made
        /// to parse the remainder of content into a Formula f using the Formula
        /// constructor.  There are then three possibilities:
        /// 
        ///   (1) If the remainder of content cannot be parsed into a Formula, a 
        ///       SpreadsheetUtilities.FormulaFormatException is thrown.
        ///       
        ///   (2) Otherwise, if changing the contents of the named cell to be f
        ///       would cause a circular dependency, a CircularException is thrown.
        ///       
        ///   (3) Otherwise, the contents of the named cell becomes f.
        /// 
        /// Otherwise, the contents of the named cell becomes content.
        /// 
        /// If an exception is not thrown, the method returns a set consisting of
        /// name plus the names of all other cells whose value depends, directly
        /// or indirectly, on the named cell.
        /// 
        /// For example, if name is A1, B1 contains A1*2, and C1 contains B1+A1, the
        /// set {A1, B1, C1} is returned.
        /// </summary>
        public override ISet<string> SetContentsOfCell(string cell_name, string content)
        {
            has_changed = true;
            string name = Normalize(cell_name);
            double number;
            if (content == null)
            {
                throw new ArgumentNullException();
            }
            else if (name == null || IsValid(name) == false)
            {
                throw new InvalidNameException();
            }
            else if (double.TryParse(content, out number))
            {
                return SetCellContents(name, number);
            }
            else if (content.StartsWith("=") && content.Length>1)
            {
                Formula formula;
                try
                {
                    string sub_content = content.Substring(1);
                    formula = new Formula(normalize_function(sub_content, Normalize));
                }
                catch
                {

                    throw new FormulaFormatException("Invalid Formula");
                }
                try
                {
                    return SetCellContents(name, formula);
                }
                catch (Exception)
                {

                    throw new CircularException();
                }
            }
            else if (content.StartsWith("=") && content.Length <= 1)
            {
                throw new FormulaFormatException("Invalid Fomula");
            }
            else
            {
                return SetCellContents(name, content);
            }
        }
Example #14
0
 public void TestEquals6()
 {
     Formula f = new Formula("x7 + 7");
     Assert.IsFalse(f != new Formula("x7 + 7"));
 }
Example #15
0
 public void TestEquals4()
 {
     Formula four = new Formula("2.0 + x7");
     Assert.IsTrue(four.Equals(new Formula("2.000 + x7")));
 }
 public void TestNormalAddition()
 {
     SpreadsheetUtilities.Formula f = new SpreadsheetUtilities.Formula("2.0 + 2.5");
     Assert.AreEqual(4.5, f.Evaluate(s => 0));
 }
Example #17
0
 /// <summary>
 /// Creates a cell with a name and contents.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="formula">formula</param>
 public Cell(String name, SpreadsheetUtilities.Formula formula)
 {
     cell_name = name;
     contents  = formula;
 }
Example #18
0
        /// <summary>
        /// If formula parameter is null, throws an ArgumentNullException.
        ///
        /// Otherwise, if name is null or invalid, throws an InvalidNameException.
        ///
        /// Otherwise, if changing the contents of the named cell to be the formula would cause a
        /// circular dependency, throws a CircularException.
        ///
        /// Otherwise, the contents of the named cell becomes formula.  The method returns a
        /// Set consisting of name plus the names of all other cells whose value depends,
        /// directly or indirectly, on the named cell.
        ///
        /// For example, if name is A1, B1 contains A1*2, and C1 contains B1+A1, the
        /// set {A1, B1, C1} is returned.
        /// </summary>
        protected override ISet <string> SetCellContents(string cell_name, SpreadsheetUtilities.Formula formula)
        {
            IEnumerable <string> backup_variables = null;
            object backup_contents = null;
            bool   had_name        = false;
            string name            = Normalize(cell_name);

            //if the formula passed in is null this throws an ArgumentNullException();
            if (formula == null)
            {
                throw new ArgumentNullException("Formula cannot be null");
            }
            //checks if the name is null or invalid if so throws a new InvalidNameException();
            if (name == null || IsValid(name) == false)
            {
                throw new InvalidNameException();
            }
            //checks if the cell with the name has been set up, if so this sets the contents of the cell to the formula passed in.
            if (spreadsheet.ContainsKey(name))
            {
                backup_variables = dependency_graph.GetDependees(name);
                backup_contents  = spreadsheet[name].get_contents();
                spreadsheet[name].set_contents(formula);
                had_name = true;
            }
            //if the cell hasn't been set up this creates a new cell and sets its contents to the text passed in.
            else
            {
                backup_contents  = " ";
                backup_variables = new HashSet <string> {
                };
                spreadsheet.Add(name, new Cell(name, formula));
            }
            IEnumerable <string> variables = formula.GetVariables(); //Gets all the variables

            dependency_graph.ReplaceDependees(name, variables);      //Replace the dependees of the name with all the variables in the formula passed in.
            //creates a hash set for the return ISet.
            ISet <string> depends = new HashSet <string> {
            };

            //looks through each item in the dependency graph and add them to the hash set to return.
            try
            {
                IEnumerable <string> recalculate_cells = GetCellsToRecalculate(name);
                foreach (string item in recalculate_cells)
                {
                    depends.Add(item);
                }
            }
            catch (CircularException)
            {
                spreadsheet[name].set_contents(backup_contents);
                dependency_graph.ReplaceDependees(name, backup_variables);
                throw new CircularException();
            }
            //sets the value of the cell
            IEnumerable <string> evaluate_cells = GetCellsToRecalculate(name);

            foreach (string cell in evaluate_cells)
            {
                Formula value_of_formula = (Formula)GetCellContents(cell);
                try
                {
                    spreadsheet[cell].set_value(value_of_formula.Evaluate(Lookup));
                }
                catch (ArgumentException)
                {
                }
            }
            //returns the hash set with all the dependents of name.
            return(depends);
        }
Example #19
0
 public void Test34()
 {
     Formula f = new Formula("5+-7(5()8");
 }
Example #20
0
 public void TestEquals3()
 {
     Formula three = new Formula("x1+y2");
     Assert.IsFalse(three.Equals(new Formula("y2+x1")));
 }
Example #21
0
 public void TestEquals8()
 {
     Formula f = new Formula("x7 + 7");
     Assert.IsFalse(f == new Formula("2.000 + x7"));
 }
Example #22
0
 public void TestEquals5()
 {
     Formula f = new Formula("x7 + 7");
     Assert.IsTrue(f != new Formula("2.000 + x7"));
 }
Example #23
0
        /// <summary>
        /// An implementation of the abstract method in AbstractSpreadsheet.
        /// <seealso cref="AbstractSpreadsheet.SetContentsOfCell"/>
        /// </summary>
        /// <param name="name"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public override ISet<string> SetContentsOfCell(string name, string content)
        {
            // Private Variable
            ISet<string> set;

            // If content is null, throws an ArgumentNullException.
            // Otherwise, if name is null or invalid, throws an InvalidNameException.
            name = CorrectInput(name, content);

            // Otherwise, if content parses as a double, the contents of the named
            // cell becomes that double.
            double d;
            if (Double.TryParse(content, out d))
                set = SetCellContents(name, d);

            // Otherwise, if content begins with the character '=', an attempt is made
            // to parse the remainder of content into a Formula f using the Formula
            // constructor.
            else if (content.Length > 0 && content[0] == '=')
            {
                // There are then three possibilities:
                //   (1) If the remainder of content cannot be parsed into a Formula, a
                //       SpreadsheetUtilities.FormulaFormatException is thrown.
                //       Be sure to check the validity of and normalize any variables.
                //   (2) Otherwise, if changing the contents of the named cell to be f
                //       would cause a circular dependency, a CircularException is thrown.
                Formula f = new Formula(content.Substring(1));
                f = NormalizeFormula(f);
                try
                {
                    foreach (string v in f.GetVariables())
                        CorrectInput(v);
                }
                catch (InvalidNameException)
                {
                    throw new FormulaFormatException(
                        String.Format("One or more variables in the formula '{0}' contained in cell {1} aren't valid.", f.ToString(), name));
                }

                //   (3) Otherwise, the contents of the named cell becomes f.
                set = SetCellContents(name, f);
            }

            // Otherwise, the contents of the named cell becomes content.
            else
                set = SetCellContents(name, content);

            // Recalculate the values of any cell dependent on the named cell, including the named cell itself.
            CalculateCellValues(name);

            //Remove any name associations to cell, reset to how it was before the cell was added.
            if (content == "")
            {
                cells.Remove(name);
            }

            // If an exception is not thrown, the method returns a set consisting of
            // name plus the names of all other cells whose value depends, directly
            // or indirectly, on the named cell.
            // For example, if name is A1, B1 contains A1*2, and C1 contains B1+A1, the
            // set {A1, B1, C1} is returned.
            return set;
        }
Example #24
0
 public void TestEquals7()
 {
     Formula f = new Formula("x7 + 7", Normalize, s => true);
     Assert.IsTrue(f == new Formula("X7 + 7"));
 }
Example #25
0
        /// <summary>
        /// An implementation of the abstract method in AbstractSpreadsheet.
        /// <seealso cref="AbstractSpreadsheet.SetCellContents(String, Formula)"/>
        /// </summary>
        /// <param name="name"></param>
        /// <param name="formula"></param>
        /// <returns></returns>
        protected override ISet<String> SetCellContents(String name, Formula formula)
        {
            // If formula parameter is null, throws an ArgumentNullException.
            // Otherwise, if name is null or invalid, throws an InvalidNameException.
            name = CorrectInput(name, formula);
            formula = NormalizeFormula(formula);

            // Otherwise, if changing the contents of the named cell to be the formula would cause a
            // circular dependency, throws a CircularException.
            IEnumerable<string> previous = dependencies.GetDependees(name);
            try
            {
                dependencies.ReplaceDependees(name, formula.GetVariables());
                GetCellsToRecalculate(name);
            }
            catch (CircularException)
            {
                dependencies.ReplaceDependees(name, previous);
                throw new CircularException();
            };

            //foreach (string v in formula.GetVariables())
            //    foreach (string d in GetCellsToRecalculate(v))
            //        if (name.Equals(d))
            //        {
            //            dependencies.ReplaceDependees(name, previous);
            //            throw new CircularException();
            //        }

            // Otherwise, the contents of the named cell becomes formula.
            Changed = true;
            GetCell(name).Contents = formula;

            // The method returns a Set consisting of name plus the names of all other
            // cells whose value depends, directly or indirectly, on the named cell.
            return new HashSet<string>(GetCellsToRecalculate(name));
        }
Example #26
0
 public void TestEquals9()
 {
     Formula f = new Formula("x7 * 7");
     Assert.IsFalse(f == new Formula("x7 * (7+3)"));
 }
Example #27
0
 public void Test28()
 {
     Formula f = new Formula("a4-a4*a4/a4");
     Assert.AreEqual(0.0, f.Evaluate(s => 3));
 }
Example #28
0
        /// <summary>
        /// Returns the formula with all the variables replaced with their normalized counterpart.
        /// </summary>
        /// <param name="f"></param>
        /// <returns></returns>
        protected Formula NormalizeFormula(Formula f)
        {
            IEnumerable<string> e = f.GetVariables();
            foreach (string s in e)
            {
                f = new Formula(Regex.Replace(f.ToString(), s, Normalize(s)));
            }

            return f;
        }
Example #29
0
        public void Test29()
        {
        
            Formula f = new Formula("x+7");
            Assert.AreEqual(9.0, f.Evaluate(s => 2));

            Formula f1 = new Formula("x+7", Normalize, Validate);
            Assert.AreEqual(11.0, f.Evaluate(s => 4));
        }
Example #30
0
        /// <summary>
        /// Event handler for "Enter" key being pressed on the cellContents text box. It sends a cell message to the server requesting
        /// a cell to be changed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cellContents_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Return)
            {
                int col;
                int row;
                spreadsheetPanel1.GetSelection(out col, out row);

                //converting the zero-based cell location to the Alphanumeric representation.
                char colChar = (char)(col + 65);
                string cell = colChar.ToString() + (row + 1);
                string contents = cellContents.Text;
                try
                {
                    if (cellContents.Text.Length > 0 && cellContents.Text.ElementAt(0) == '=')
                    {
                        //check to see if it can make a new formula. This will check for format errors before sending to server.
                        Formula temporaryFormula = new Formula(cellContents.Text.Substring(1), ss.Normalize, ss.IsValid);
                        contents = "=" + temporaryFormula.ToString();
                    }
                    //sends cell name and cell contents to server for synchronization.
                    comm.editCell(cell, contents);
                }
                catch (FormulaFormatException ex)
                {
                    System.Windows.Forms.MessageBox.Show(cell + " has an incorrect formula.");
                }
            }
        }
Example #31
0
 public void Test30()
 {
     Formula f = new Formula("5+7(5)8");
 }
Example #32
0
 /// <summary>
 /// Sets the Formula of the current Cell.
 /// </summary>
 /// <param name="formula"></param>
 public void setFormula(Formula formula)
 {
     this.formula = formula;
     this.isText = false;
     this.isFormula = true;
     this.isNumber = false;
 }
Example #33
0
 public void Test31()
 {
     Formula f = new Formula("5+7(5()8");
 }
 // MODIFIED PROTECTION FOR PS5
 /// <summary>
 /// If formula parameter is null, throws an ArgumentNullException.
 /// 
 /// Otherwise, if name is null or invalid, throws an InvalidNameException.
 /// 
 /// Otherwise, if changing the contents of the named cell to be the formula would cause a 
 /// circular dependency, throws a CircularException.
 /// 
 /// Otherwise, the contents of the named cell becomes formula.  The method returns a
 /// Set consisting of name plus the names of all other cells whose value depends,
 /// directly or indirectly, on the named cell.
 /// 
 /// For example, if name is A1, B1 contains A1*2, and C1 contains B1+A1, the
 /// set {A1, B1, C1} is returned.
 /// </summary>
 protected abstract ISet<String> SetCellContents(String name, Formula formula);
Example #35
0
 public void Test32()
 {
     Formula f = new Formula("5+7^5X%5()8");
 }