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); }
/// <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); }
/// <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))); }
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); }
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; }
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); }
public void Test33() { Formula f = new Formula("4-3*1/a4"); Assert.IsTrue(f.Evaluate(s => 0) is FormulaError); }
/// <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; }
/// <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); } }
public void TestEquals6() { Formula f = new Formula("x7 + 7"); Assert.IsFalse(f != new Formula("x7 + 7")); }
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)); }
/// <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; }
/// <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); }
public void Test34() { Formula f = new Formula("5+-7(5()8"); }
public void TestEquals3() { Formula three = new Formula("x1+y2"); Assert.IsFalse(three.Equals(new Formula("y2+x1"))); }
public void TestEquals8() { Formula f = new Formula("x7 + 7"); Assert.IsFalse(f == new Formula("2.000 + x7")); }
public void TestEquals5() { Formula f = new Formula("x7 + 7"); Assert.IsTrue(f != new Formula("2.000 + x7")); }
/// <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; }
public void TestEquals7() { Formula f = new Formula("x7 + 7", Normalize, s => true); Assert.IsTrue(f == new Formula("X7 + 7")); }
/// <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)); }
public void TestEquals9() { Formula f = new Formula("x7 * 7"); Assert.IsFalse(f == new Formula("x7 * (7+3)")); }
public void Test28() { Formula f = new Formula("a4-a4*a4/a4"); Assert.AreEqual(0.0, f.Evaluate(s => 3)); }
/// <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; }
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)); }
/// <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."); } } }
public void Test30() { Formula f = new Formula("5+7(5)8"); }
/// <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; }
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);
public void Test32() { Formula f = new Formula("5+7^5X%5()8"); }