Ishrar G
Ishrar G

Ishrar G

Create Dynamic Mathematical Formula in C#

Create Dynamic Mathematical Formula in C#

Ready to use solution for any dynamic mathematical formula

Ishrar G's photo
Ishrar G
·Jul 2, 2022·

4 min read

Play this article

Why do we need Dynamic Math Formula?

I was working on a project yesterday, where I was uploading items on the Shopify website in bulk by looping on Excel.

The user's requirement was to create items by changing the sales price with the formula and the user must be able to change the formula for the sales price based on cost.

I was literally worried about giving this solution in a short time because I planned to build this thing.

Currently, the client has a formula for the sales price = ItemCost * 2 +15. They want to change the formula based on different scenarios.

I built it using the solution explained on StackOverflow here

This answer on Stackoverflow explained the solution perfectly for my requirement.

Wise people always Google it before inventing.

Build a Class to Calculate Dynamic Formula in C

Have a look at the class and the method which handles the formula for Multiplication, division, addition and subtraction.

public class DynamicFormula
{
    /// <summary>
    /// This simply stores a variable name and its value so when this key is found in a expression it gets the value accordingly.
    /// </summary>
    public Dictionary<string, double> Variables { get; private set; }

    /// <summary>
    /// The expression itself, each value and operation must be separated with SPACES. The expression does not support PARENTHESES at this point.
    /// </summary>
    public string Expression { get; set; }

    public DynamicFormula()
    {
        this.Variables = new Dictionary<string, double>();
    }

    public double CalculateResult()
    {
        if (string.IsNullOrWhiteSpace(this.Expression))
            throw new Exception("An expression must be defined in the Expression property.");

        double? result = null;
        string operation = string.Empty;

        //This will be necessary for priorities operations such as parentheses, etc... It is not being used at this point.
        List<double> aux = new List<double>();  

        foreach (var lexema in Expression.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries))
        {
            //If it is an operator
            if (lexema == "*" || lexema == "/" || lexema == "+" || lexema == "-")
            {
                operation = lexema;
            }
            else //It is a number or a variable
            {
                double value = double.MinValue;
                if (Variables.ContainsKey(lexema.ToLower())) //If it is a variable, let's get the variable value
                    value = Variables[lexema.ToLower()];
                else //It is just a number, let's just parse
                    value = double.Parse(lexema);

                if (!result.HasValue) //No value has been assigned yet
                {
                    result = value;
                }
                else
                {
                    switch (operation) //Let's check the operation we should perform
                    {
                        case "*":
                            result = result.Value * value;
                            break;
                        case "/":
                            result = result.Value / value;
                            break;
                        case "+":
                            result = result.Value + value;
                            break;
                        case "-":
                            result = result.Value - value;
                            break;
                        default:
                            throw new Exception("The expression is not properly formatted.");
                    }
                }
            }
        }

        if (result.HasValue)
            return result.Value;
        else
            throw new Exception("The operation could not be completed, a result was not obtained.");
    }
    /// <summary>
    /// Add variables to the dynamic math formula. The variable should be properly declared.
    /// </summary>
    /// <param name="variableDeclaration">Should be declared as "VariableName=VALUE" without spaces</param>
    public void AddVariable(string variableDeclaration)
    {            
        if (!string.IsNullOrWhiteSpace(variableDeclaration))
        {
            var variable = variableDeclaration.ToLower().Split('=');    //Let's make sure the variable's name is LOWER case and then get its name/value
            string variableName = variable[0];
            double variableValue = 0;

            if (double.TryParse(variable[1], out variableValue))
                this.Variables.Add(variableName, variableValue);
            else
                throw new ArgumentException("Variable value is not a number");
        }
        else
        {
            //Could throw an exception... or just ignore as it not important...
        }
    }
}

The Above class Accepts Mathematical Expression and Variable Values to be used in Expression. When we execute CalculateResult() method it gives calculated result.

Here is what I did in my project, I just created a simple object of DynamicFormula, and passed the Expression and Variables. Just by calling CalculateResult() method my result is there. Have a look at the code in my project

Calculating Dynamic Formula using Expression and Variables in C

string priceFormula = CommonFunctions.EnvironmentSettings.PriceFormula;
try
{
    //This was my static formula before
    //decimal price = decimal.Parse(i.Variant_Cost);
    //price = (price * 2) + 10;
    //i.Variant_Price = price.ToString();
    //------------------------------------------
    DynamicFormula f = new DynamicFormula();
    f.Expression = priceFormula;
    f.AddVariable("cost=" + i.Variant_Cost);
    double result = f.CalculateResult();
    i.Variant_Price = result.ToString();
}
catch (Exception ex)
{
    i.Variant_Price = "";
}

image.png

If you have such a similar requirement you can use this solution given by luishg.

Did you find this article valuable?

Support Ishrar G by becoming a sponsor. Any amount is appreciated!

Learn more about Hashnode Sponsors
 
Share this