//This is a C# question and I am super stuck on this, please any help with exple
ID: 3878805 • Letter: #
Question
//This is a C# question and I am super stuck on this, please any help with explenation would be highly appreciated...THANK YOU!!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Formulas
{
///
/// Represents formulas written in standard infix notation using standard precedence
/// rules. Provides a means to evaluate Formulas. Formulas can be composed of
/// non-negative floating-point numbers, variables, left and right parentheses, and
/// the four binary operator symbols +, -, *, and /. (The unary operators + and -
/// are not allowed.)
///
public class Formula
{
private bool lpPattern;
///
/// Creates a Formula from a string that consists of a standard infix expression composed
/// from non-negative floating-point numbers (using C#-like syntax for double/int literals),
/// variable symbols (a letter followed by zero or more letters and/or digits), left and right
/// parentheses, and the four binary operator symbols +, -, *, and /. White space is
/// permitted between tokens, but is not required.
///
/// Examples of a valid parameter to this constructor are:
/// "2.5e9 + x5 / 17"
/// "(5 * 2) + 8"
/// "x*y-2+35/9"
///
/// Examples of invalid parameters are:
/// "_"
/// "-5.3"
/// "2 5 + 3"
///
/// If the formula is syntacticaly invalid, throws a FormulaFormatException with an
/// explanatory Message.
///
public Formula(String formula)
{
//converts formula string to lowercase.
formula = formula.ToLower();
//makes a stack to hold values and operators
Stack valStack = new Stack();
Stack OpeStack = new Stack();
//The sequence "\" matches "" and "(" matches "(".
//tokenizing and splitting it
//string[] token = Regex.Split(formula, "(\()|(\))|(-)|(\+)|(\*)|(/)");
// starts to store tokens according to GetTokens
string[] token = GetTokens(formula).ToArray();
//first check to see if its empty or not valid
if (token == null || token.Length == 0)
{
throw new FormulaFormatException("Not valid");
}
if (IsOperator(token[0]))
{
if (!"(".Equals(token[0]))
{
//Starting w/ invalid token
throw new FormulaFormatException("Only operator formula may start with is '('");
}
}
foreach (String token in tokens)
{
int value;
if (" ".Equals(token) || "".Equals(token))
{
continue; //ignore blank space
}
if (IsNumeric(token, out value))
{
if (OpeStack.Count != 0 && ("*".Equals(OpeStack.Peek()) || "/".Equals(OpeStack.Peek())))
{
//multiplication or division, time to evaluate and push result
valStack.Push(PerformEvaluation(valStack.Pop(), value, OpeStack.Pop()));
}
else
{
//Just a value, no division or mult, just push to stack
valStack.Push(value);
}
}
}
bool IsOperator(string tokenn)
{
return "*".Equals(tokenn) || "+".Equals(tokenn) || "-".Equals(tokenn) || "/".Equals(tokenn) || "(".Equals(tokenn) || ")".Equals(tokenn);
}
bool IsNumeric(String tokenz, out int value)
{
value = 0;
return int.TryParse(tokenz, out value);
}
else if (IsOperator(token))
{
if (")".Equals(token))
{ //closing parens, we need to evaluate inner
//Must contain at least two values on the stack or the closing paren is invalid
if (valStack.Count < 2)
{
//throw new ArgumentException("Invalid formula, not enough values inside the parentheses.");
}
//get the previous value
int prevValue = valStack.Pop();
//now get the previous operator
String prevOperator = OpeStack.Pop();
while (!"(".Equals(prevOperator))
{
//need to have a value on the stack to perform another operation
if (valStack.Count == 0)
{
throw new ArgumentException("Invalid formula, expected a left value inside the parens, but none was found.");
}
int leftValue = valStack.Pop();
prevValue = PerformEvaluation(leftValue, prevValue, prevOperator);
//no previous operators and we didn't find the '(' formula is invalid
if (OpeStack.Count == 0)
{
throw new ArgumentException("Invalid formula, expected a '(' with the ')' but wasn't found");
}
//get the next previous operator and do again.
prevOperator = OpeStack.Pop();
}
//found the opening parens, we are done, let's just push the value to the stack
// we discard the parens here since we are done with evaluation.
valueStack.Push(prevValue);
//one last check if * or / on stack we need to perform this now
if (OpeStack.Count != 0 && ("*".Equals(OpeStack.Peek()) || "/".Equals(OpeStack.Peek())))
{
if (valStack.Count < 2)
{
throw new ArgumentException("Invalid formula, unable to perform operation, as 2 values are not on the stack.");
}
int right = valStack.Pop();
int left = valStack.Pop();
valStack.Push(PerformEvaluation(left, right, OpeStack.Pop()));
}
}
else if ("+".Equals(token) || "-".Equals(token))
{
if (OpeStack.Count != 0 && ("+".Equals(OpeStack.Peek()) || "-".Equals(OpeStack.Peek())))
{
//we got a + or - and already have a + or - on the stack. Evaluate now
if (valStack.Count < 2)
{
throw new ArgumentException("Invalid formula, attempted to perform operation and not enough values on stack");
}
int right = valStack.Pop();
int left = valStack.Pop();
valStack.Push(PerformEvaluation(left, right, OpeStack.Pop()));
}
OpeStack.Push(token);
}
else
{
OpeStack.Push(token);
}
}
else
{
//must be a variable - delegate should throw exception if not found
int lookedUpValue = variableLookup(token.Trim());
if (OpeStack.Count != 0 && ("*".Equals(OpeStack.Peek()) || "/".Equals(OpeStack.Peek())))
{
//multiplication or division, time to evaluate and push result
if (valStack.Count == 0)
{
throw new ArgumentException("Invalid formula, expected another value for evaluation and none was found");
}
valStack.Push(PerformEvaluation(valStack.Pop(), lookedUpValue, OpeStack.Pop()));
}
else
{
//Just a value, no division or mult, just push to stack
valStack.Push(lookedUpValue);
}
}
if (OpeStack.Count == 0)
{
if (valStack.Count != 1)
{
throw new ArgumentException("Invalid formula, invalid value count left at end of operation");
}
return valStack.Pop();
}
else
{
if (valStack.Count != 2 && OpeStack.Count != 1)
{
throw new ArgumentException("Invalid formula, too many operators and/or values left at end of Evaluation");
}
int right = valStack.Pop();
int left = valStack.Pop();
//perform final evaluation
return PerformEvaluation(left, right, OpeStack.Pop());
}
}
}
}
///
/// Evaluates this Formula, using the Lookup delegate to determine the values of variables. (The
/// delegate takes a variable name as a parameter and returns its value (if it has one) or throws
/// an UndefinedVariableException (otherwise). Uses the standard precedence rules when doing the evaluation.
///
/// If no undefined variables or divisions by zero are encountered when evaluating
/// this Formula, its value is returned. Otherwise, throws a FormulaEvaluationException
/// with an explanatory Message.
///
public double Evaluate(Lookup lookup)
{
return 0;
}
///
/// Given a formula, enumerates the tokens that compose it. Tokens are left paren,
/// right paren, one of the four operator symbols, a string consisting of a letter followed by
/// zero or more digits and/or letters, a double literal, and anything that doesn't
/// match one of those patterns. There are no empty tokens, and no token contains white space.
///
private static IEnumerable GetTokens(String formula)
{
// Patterns for individual tokens.
// NOTE: These patterns are designed to be used to create a pattern to split a string into tokens.
// For example, the opPattern will match any string that contains an operator symbol, such as
// "abc+def". If you want to use one of these patterns to match an entire string (e.g., make it so
// the opPattern will match "+" but not "abc+def", you need to add ^ to the beginning of the pattern
// and $ to the end (e.g., opPattern would need to be @"^[+-*/]$".)
String lpPattern = @"(";
String rpPattern = @")";
String opPattern = @"[+-*/]";
String varPattern = @"[a-zA-Z][0-9a-zA-Z]*";
// PLEASE NOTE: I have added white space to this regex to make it more readable.
// When the regex is used, it is necessary to include a parameter that says
// embedded white space should be ignored. See below for an example of this.
String doublePattern = @"(?: d+.d* | d*.d+ | d+ ) (?: e[+-]?d+)?";
String spacePattern = @"s+";
// Overall pattern. It contains embedded white space that must be ignored when
// it is used. See below for an example of this. This pattern is useful for
// splitting a string into tokens.
String splittingPattern = String.Format("({0}) | ({1}) | ({2}) | ({3}) | ({4}) | ({5})",
lpPattern, rpPattern, opPattern, varPattern, doublePattern, spacePattern);
// Enumerate matching tokens that don't consist solely of white space.
// PLEASE NOTE: Notice the second parameter to Split, which says to ignore embedded white space
/// in the pattern.
foreach (String s in Regex.Split(formula, splittingPattern, RegexOptions.IgnorePatternWhitespace))
{
if (!Regex.IsMatch(s, @"^s*$", RegexOptions.Singleline))
{
yield return s;
}
}
}
}
///
/// A Lookup method is one that maps some strings to double values. Given a string,
/// such a function can either return a double (meaning that the string maps to the
/// double) or throw an UndefinedVariableException (meaning that the string is unmapped
/// to a value. Exactly how a Lookup method decides which strings map to doubles and which
/// don't is up to the implementation of the method.
///
public delegate double Lookup(string var);
///
/// Used to report that a Lookup delegate is unable to determine the value
/// of a variable.
///
[Serializable]
public class UndefinedVariableException : Exception
{
///
/// Constructs an UndefinedVariableException containing whose message is the
/// undefined variable.
///
///
public UndefinedVariableException(String variable)
: base(variable)
{
}
}
///
/// Used to report syntactic errors in the parameter to the Formula constructor.
///
[Serializable]
public class FormulaFormatException : Exception
{
///
/// Constructs a FormulaFormatException containing the explanatory message.
///
public FormulaFormatException(String message) : base(message)
{
}
}
///
/// Used to report errors that occur when evaluating a Formula.
///
[Serializable]
public class FormulaEvaluationException : Exception
{
///
/// Constructs a FormulaEvaluationException containing the explanatory message.
///
public FormulaEvaluationException(String message) : base(message)
{
}
}
sing System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Formulas;
namespace FormulaTestCases
{
///
/// These test cases are in no sense comprehensive! They are intended to show you how
/// client code can make use of the Formula class, and to show you how to create your
/// own (which we strongly recommend). To run them, pull down the Test menu and do
/// Run > All Tests.
///
[TestClass]
public class UnitTests
{
///
/// This tests that a syntactically incorrect parameter to Formula results
/// in a FormulaFormatException.
///
[TestMethod]
[ExpectedException(typeof(FormulaFormatException))]
public void Construct1()
{
Formula f = new Formula("_");
}
///
/// This is another syntax error
///
[TestMethod]
[ExpectedException(typeof(FormulaFormatException))]
public void Construct2()
{
Formula f = new Formula("2++3");
}
///
/// Another syntax error.
///
[TestMethod]
[ExpectedException(typeof(FormulaFormatException))]
public void Construct3()
{
Formula f = new Formula("2 3");
}
///
/// Makes sure that "2+3" evaluates to 5. Since the Formula
/// contains no variables, the delegate passed in as the
/// parameter doesn't matter. We are passing in one that
/// maps all variables to zero.
///
[TestMethod]
public void Evaluate1()
{
Formula f = new Formula("2+3");
Assert.AreEqual(f.Evaluate(v => 0), 5.0, 1e-6);
}
///
/// The Formula consists of a single variable (x5). The value of
/// the Formula depends on the value of x5, which is determined by
/// the delegate passed to Evaluate. Since this delegate maps all
/// variables to 22.5, the return value should be 22.5.
///
[TestMethod]
public void Evaluate2()
{
Formula f = new Formula("x5");
Assert.AreEqual(f.Evaluate(v => 22.5), 22.5, 1e-6);
}
///
/// Here, the delegate passed to Evaluate always throws a
/// UndefinedVariableException (meaning that no variables have
/// values). The test case checks that the result of
/// evaluating the Formula is a FormulaEvaluationException.
///
[TestMethod]
[ExpectedException(typeof(FormulaEvaluationException))]
public void Evaluate3()
{
Formula f = new Formula("x + y");
f.Evaluate(v => { throw new UndefinedVariableException(v); });
}
///
/// The delegate passed to Evaluate is defined below. We check
/// that evaluating the formula returns in 10.
///
[TestMethod]
public void Evaluate4()
{
Formula f = new Formula("x + y");
Assert.AreEqual(f.Evaluate(Lookup4), 10.0, 1e-6);
}
///
/// This uses one of each kind of token.
///
[TestMethod]
public void Evaluate5 ()
{
Formula f = new Formula("(x + y) * (z / x) * 1.0");
Assert.AreEqual(f.Evaluate(Lookup4), 20.0, 1e-6);
}
///
/// A Lookup method that maps x to 4.0, y to 6.0, and z to 8.0.
/// All other variables result in an UndefinedVariableException.
///
///
///
public double Lookup4(String v)
{
switch (v)
{
case "x": return 4.0;
case "y": return 6.0;
case "z": return 8.0;
default: throw new UndefinedVariableException(v);
}
}
}
}
Explanation / Answer
// The System.Collections.Generic namespace contains interfaces and classes that define generic collections, which allow users to create strongly typed collections that provide better type safety and performance than non-generic strongly typed collections.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Formulas
{
///
/// Represents formulas written in standard infix notation using standard precedence
/// rules. Provides a means to evaluate Formulas. Formulas can be composed of
/// non-negative floating-point numbers, variables, left and right parentheses, and
/// the four binary operator symbols +, -, *, and /. (The unary operators + and -
/// are not allowed.)
///
public class Formula
{
// private class members.
private bool lpPattern;
///
/// Creates a Formula from a string that consists of a standard infix expression composed
/// from non-negative floating-point numbers (using C#-like syntax for double/int literals),
/// variable symbols (a letter followed by zero or more letters and/or digits), left and right
/// parentheses, and the four binary operator symbols +, -, *, and /. White space is
/// permitted between tokens, but is not required.
///
/// Examples of a valid parameter to this constructor are:
/// "2.5e9 + x5 / 17"
/// "(5 * 2) + 8"
/// "x*y-2+35/9"
///
/// Examples of invalid parameters are:
/// "_"
/// "-5.3"
/// "2 5 + 3"
///
/// If the formula is syntacticaly invalid, throws a FormulaFormatException with an
/// explanatory Message.
///
public Formula(String formula)
{
//converts formula string to lowercase.
formula = formula.ToLower();
//makes a stack to hold values and operators
Stack valStack = new Stack();
Stack OpeStack = new Stack();
//The sequence "\" matches "" and "(" matches "(".
//tokenizing and splitting it
//string[] token = Regex.Split(formula, "(\()|(\))|(-)|(\+)|(\*)|(/)");
// starts to store tokens according to GetTokens
string[] token = GetTokens(formula).ToArray();
//first check to see if its empty or not valid
if (token == null || token.Length == 0)
{
throw new FormulaFormatException("Not valid");
}
/// checking if token is operator or not.
if (IsOperator(token[0]))
{
if (!"(".Equals(token[0]))
{
//Starting w/ invalid token
throw new FormulaFormatException("Only operator formula may start with is '('");
}
}
foreach (String token in tokens) // foreach loop for tokens,.
{
int value;
if (" ".Equals(token) || "".Equals(token))
{
continue; //ignore blank space
}
if (IsNumeric(token, out value))
{
if (OpeStack.Count != 0 && ("*".Equals(OpeStack.Peek()) || "/".Equals(OpeStack.Peek())))
{
//multiplication or division, time to evaluate and push result
valStack.Push(PerformEvaluation(valStack.Pop(), value, OpeStack.Pop()));
}
else
{
//Just a value, no division or mult, just push to stack
valStack.Push(value);
}
}
}
bool IsOperator(string tokenn)
{
return "*".Equals(tokenn) || "+".Equals(tokenn) || "-".Equals(tokenn) || "/".Equals(tokenn) || "(".Equals(tokenn) || ")".Equals(tokenn);
}
bool IsNumeric(String tokenz, out int value)
{
value = 0;
return int.TryParse(tokenz, out value);
}
else if (IsOperator(token))
{
if (")".Equals(token))
{ //closing parens, we need to evaluate inner
//Must contain at least two values on the stack or the closing paren is invalid
if (valStack.Count < 2)
{
//throw new ArgumentException("Invalid formula, not enough values inside the parentheses.");
}
//get the previous value
int prevValue = valStack.Pop();
//now get the previous operator
String prevOperator = OpeStack.Pop();
while (!"(".Equals(prevOperator))
{
//need to have a value on the stack to perform another operation
if (valStack.Count == 0)
{
throw new ArgumentException("Invalid formula, expected a left value inside the parens, but none was found.");
}
int leftValue = valStack.Pop();
prevValue = PerformEvaluation(leftValue, prevValue, prevOperator);
//no previous operators and we didn't find the '(' formula is invalid
if (OpeStack.Count == 0)
{
throw new ArgumentException("Invalid formula, expected a '(' with the ')' but wasn't found");
}
//get the next previous operator and do again.
prevOperator = OpeStack.Pop();
}
//found the opening parens, we are done, let's just push the value to the stack
// we discard the parens here since we are done with evaluation.
valueStack.Push(prevValue);
//one last check if * or / on stack we need to perform this now
if (OpeStack.Count != 0 && ("*".Equals(OpeStack.Peek()) || "/".Equals(OpeStack.Peek())))
{
if (valStack.Count < 2)
{
throw new ArgumentException("Invalid formula, unable to perform operation, as 2 values are not on the stack.");
}
int right = valStack.Pop();
int left = valStack.Pop();
valStack.Push(PerformEvaluation(left, right, OpeStack.Pop()));
}
}
else if ("+".Equals(token) || "-".Equals(token))
{
if (OpeStack.Count != 0 && ("+".Equals(OpeStack.Peek()) || "-".Equals(OpeStack.Peek())))
{
//we got a + or - and already have a + or - on the stack. Evaluate now
if (valStack.Count < 2)
{
throw new ArgumentException("Invalid formula, attempted to perform operation and not enough values on stack");
}
int right = valStack.Pop();
int left = valStack.Pop();
valStack.Push(PerformEvaluation(left, right, OpeStack.Pop()));
}
OpeStack.Push(token);
}
else
{
OpeStack.Push(token);
}
}
else
{
//must be a variable - delegate should throw exception if not found
int lookedUpValue = variableLookup(token.Trim());
if (OpeStack.Count != 0 && ("*".Equals(OpeStack.Peek()) || "/".Equals(OpeStack.Peek())))
{
//multiplication or division, time to evaluate and push result
if (valStack.Count == 0)
{
throw new ArgumentException("Invalid formula, expected another value for evaluation and none was found");
}
valStack.Push(PerformEvaluation(valStack.Pop(), lookedUpValue, OpeStack.Pop()));
}
else
{
//Just a value, no division or mult, just push to stack
valStack.Push(lookedUpValue);
}
}
if (OpeStack.Count == 0)
{
if (valStack.Count != 1)
{
throw new ArgumentException("Invalid formula, invalid value count left at end of operation");
}
return valStack.Pop();
}
else
{
if (valStack.Count != 2 && OpeStack.Count != 1)
{
throw new ArgumentException("Invalid formula, too many operators and/or values left at end of Evaluation");
}
int right = valStack.Pop();
int left = valStack.Pop();
//perform final evaluation
return PerformEvaluation(left, right, OpeStack.Pop());
}
}
}
}
///
/// Evaluates this Formula, using the Lookup delegate to determine the values of variables. (The
/// delegate takes a variable name as a parameter and returns its value (if it has one) or throws
/// an UndefinedVariableException (otherwise). Uses the standard precedence rules when doing the evaluation.
///
/// If no undefined variables or divisions by zero are encountered when evaluating
/// this Formula, its value is returned. Otherwise, throws a FormulaEvaluationException
/// with an explanatory Message.
///
public double Evaluate(Lookup lookup)
{
return 0;
}
///
/// Given a formula, enumerates the tokens that compose it. Tokens are left paren,
/// right paren, one of the four operator symbols, a string consisting of a letter followed by
/// zero or more digits and/or letters, a double literal, and anything that doesn't
/// match one of those patterns. There are no empty tokens, and no token contains white space.
///
private static IEnumerable GetTokens(String formula)
{
// Patterns for individual tokens.
// NOTE: These patterns are designed to be used to create a pattern to split a string into tokens.
// For example, the opPattern will match any string that contains an operator symbol, such as
// "abc+def". If you want to use one of these patterns to match an entire string (e.g., make it so
// the opPattern will match "+" but not "abc+def", you need to add ^ to the beginning of the pattern
// and $ to the end (e.g., opPattern would need to be @"^[+-*/]$".)
String lpPattern = @"(";
String rpPattern = @")";
String opPattern = @"[+-*/]";
String varPattern = @"[a-zA-Z][0-9a-zA-Z]*";
// PLEASE NOTE: I have added white space to this regex to make it more readable.
// When the regex is used, it is necessary to include a parameter that says
// embedded white space should be ignored. See below for an example of this.
String doublePattern = @"(?: d+.d* | d*.d+ | d+ ) (?: e[+-]?d+)?";
String spacePattern = @"s+";
// Overall pattern. It contains embedded white space that must be ignored when
// it is used. See below for an example of this. This pattern is useful for
// splitting a string into tokens.
String splittingPattern = String.Format("({0}) | ({1}) | ({2}) | ({3}) | ({4}) | ({5})",
lpPattern, rpPattern, opPattern, varPattern, doublePattern, spacePattern);
// Enumerate matching tokens that don't consist solely of white space.
// PLEASE NOTE: Notice the second parameter to Split, which says to ignore embedded white space
/// in the pattern.
foreach (String s in Regex.Split(formula, splittingPattern, RegexOptions.IgnorePatternWhitespace))
{
if (!Regex.IsMatch(s, @"^s*$", RegexOptions.Singleline))
{
yield return s;
}
}
}
}
///
/// A Lookup method is one that maps some strings to double values. Given a string,
/// such a function can either return a double (meaning that the string maps to the
/// double) or throw an UndefinedVariableException (meaning that the string is unmapped
/// to a value. Exactly how a Lookup method decides which strings map to doubles and which
/// don't is up to the implementation of the method.
///
public delegate double Lookup(string var);
///
/// Used to report that a Lookup delegate is unable to determine the value
/// of a variable.
///
[Serializable]
public class UndefinedVariableException : Exception
{
///
/// Constructs an UndefinedVariableException containing whose message is the
/// undefined variable.
///
///
public UndefinedVariableException(String variable)
: base(variable)
{
}
}
///
/// Used to report syntactic errors in the parameter to the Formula constructor.
///
[Serializable]
public class FormulaFormatException : Exception
{
///
/// Constructs a FormulaFormatException containing the explanatory message.
///
public FormulaFormatException(String message) : base(message)
{
}
}
///
/// Used to report errors that occur when evaluating a Formula.
///
[Serializable]
public class FormulaEvaluationException : Exception
{
///
/// Constructs a FormulaEvaluationException containing the explanatory message.
///
public FormulaEvaluationException(String message) : base(message)
{
}
}
sing System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Formulas;
namespace FormulaTestCases
{
///
/// These test cases are in no sense comprehensive! They are intended to show you how
/// client code can make use of the Formula class, and to show you how to create your
/// own (which we strongly recommend). To run them, pull down the Test menu and do
/// Run > All Tests.
///
[TestClass]
public class UnitTests
{
///
/// This tests that a syntactically incorrect parameter to Formula results
/// in a FormulaFormatException.
///
[TestMethod]
[ExpectedException(typeof(FormulaFormatException))]
public void Construct1()
{
Formula f = new Formula("_");
}
///
/// This is another syntax error
///
[TestMethod]
[ExpectedException(typeof(FormulaFormatException))]
public void Construct2()
{
Formula f = new Formula("2++3");
}
///
/// Another syntax error.
///
[TestMethod]
[ExpectedException(typeof(FormulaFormatException))]
public void Construct3()
{
Formula f = new Formula("2 3");
}
///
/// Makes sure that "2+3" evaluates to 5. Since the Formula
/// contains no variables, the delegate passed in as the
/// parameter doesn't matter. We are passing in one that
/// maps all variables to zero.
///
[TestMethod]
public void Evaluate1()
{
Formula f = new Formula("2+3");
Assert.AreEqual(f.Evaluate(v => 0), 5.0, 1e-6);
}
///
/// The Formula consists of a single variable (x5). The value of
/// the Formula depends on the value of x5, which is determined by
/// the delegate passed to Evaluate. Since this delegate maps all
/// variables to 22.5, the return value should be 22.5.
///
[TestMethod]
public void Evaluate2()
{
Formula f = new Formula("x5");
Assert.AreEqual(f.Evaluate(v => 22.5), 22.5, 1e-6);
}
///
/// Here, the delegate passed to Evaluate always throws a
/// UndefinedVariableException (meaning that no variables have
/// values). The test case checks that the result of
/// evaluating the Formula is a FormulaEvaluationException.
///
[TestMethod]
[ExpectedException(typeof(FormulaEvaluationException))]
public void Evaluate3()
{
Formula f = new Formula("x + y");
f.Evaluate(v => { throw new UndefinedVariableException(v); });
}
///
/// The delegate passed to Evaluate is defined below. We check
/// that evaluating the formula returns in 10.
///
[TestMethod]
public void Evaluate4()
{
Formula f = new Formula("x + y");
Assert.AreEqual(f.Evaluate(Lookup4), 10.0, 1e-6);
}
///
/// This uses one of each kind of token.
///
[TestMethod]
public void Evaluate5 ()
{
Formula f = new Formula("(x + y) * (z / x) * 1.0");
Assert.AreEqual(f.Evaluate(Lookup4), 20.0, 1e-6);
}
///
/// A Lookup method that maps x to 4.0, y to 6.0, and z to 8.0.
/// All other variables result in an UndefinedVariableException.
///
///
///
public double Lookup4(String v)
{
switch (v)
{
case "x": return 4.0;
case "y": return 6.0;
case "z": return 8.0;
default: throw new UndefinedVariableException(v);
}
}
}
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.