Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

//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);

}

}

}

}