Marc
Marc

Reputation: 13

How to use formulas from a text file?

I have an desktop c# application which uses formulas to calculate values based on input from the user.

I was wandering if there is a way to take the formula from a text file and use it instead of having it hardcoded, this would make it easy to change formulas once program is compiled.

The problem is converting this string from the text file into the formula which is usable in the code.

Thank you

Upvotes: 0

Views: 2108

Answers (3)

King King
King King

Reputation: 63367

I think you may want to try parsing the formula string directly to calculate out the result. However using XML to store your formula is also a good idea (although you have to type yourself the formula converted from the actual formula, to do this, you have to learn a little about the XML structure which is used to express the formula. Don't worry, it's simple). First I talk a little about the XML structure expressing a formula. It has 2 types of node:

  1. Operand node: This node has name operand and has 1 attribute called value and doesn't have any child element. Its value can be a number or a variable (placeholder) so that you can pass some value into at runtime. Examples:

    <operand value="1234"/>
    <operand value="x"/>
    
  2. Operator node: This node has the similar name to the operator it supports. For simplicity, I suppose your formula supports only 4 operators: +, -, *, /.Addition is expressed by tag <add>, subtraction is expressed by tag <sub>, multiplication is expressed by tag <mul> and division is expressed by tag <div>. Each operator node has 2 elements (because the operator is binary). Each element is an operand. This is not strict to the operand node mentioned above, it can be another operator node. That's all to know about the structure of the XML. Examples:

    //expression of (x + y)
    <add>
      <operand value="x"/>
      <operand value="y"/>
    </add>
    

The following XML is an example of the formula f(x,y) = (x + y - x/y) * (x-y) / 5. This formula requires 2 variables to be computed at runtime.

<mul>
  <sub>
     <add>
        <operand value="x"/>
        <operand value="y"/>
     </add>
     <div>
        <operand value="x"/>
        <operand value="y"/>
     </div>
  </sub>
  <div>
     <sub>
        <operand value="x"/>
        <operand value="y"/>
     </sub>
     <operand value="5"/>
  </div>
</mul>

Here is the code to deal with it:

public class ArgumentInfo
{
   public string Name { get; set; }
   public double Value { get; set; }
}
public double ComputeNode(XElement node, params ArgumentInfo[] args)
{
        var operands = node.Elements().ToList();
        if (operands.Count == 0)
        {
            if (node.Name != "operand") throw new ArgumentException("XML formula error! Please check it");
            ArgumentInfo o = args.FirstOrDefault(x => x.Name == node.Attribute("value").Value);
            return o == null ? double.Parse(node.Attribute("value").Value) : o.Value;
        }    
        if (operands.Count != 2) throw new ArgumentException("XML formula error! Please check it");    
        var a = ComputeNode(operands[0], args);
        var b = ComputeNode(operands[1], args);
        if (node.Name == "add") return a + b;
        else if (node.Name == "sub") return a - b;
        else if (node.Name == "mul") return a * b;
        else return a / b;            
}
public double Compute(string xmlFormula, params ArgumentInfo[] args)
{
        XDocument doc = XDocument.Parse(xmlFormula);
        return ComputeNode(doc.Root, args);
}
public double ComputeFormulaFromPath(string xmlFormulaPath, params ArgumentInfo[] args)
{
        XDocument doc = XDocument.Load(xmlFormulaPath);
        return ComputeNode(doc.Root, args);
}
//Example f(x,y) = (x + y - x/y) * (x-y) / 5 with (x,y) = (10,20)
var result = ComputeFormulaFromPath(@"E:\yourFormula.xml", new ArgumentInfo {Name = "x", Value = 10}, 
                                                           new ArgumentInfo {Name="y",Value=20});
//The result is -59

You can also define some tag called <formula> to express a formula and you can define many formulas in the same xml file.

Upvotes: 1

user240141
user240141

Reputation:

I dont think you can use formula's dynamically, as per your approach. I am not saying it's not possible but making it possible will take more extra stuffing in your app.

Take a simpler case

Your Text File has few simple formulas in format given below:

Add : a+b
Simple Interest : (P*R*T)/100
Progression = 1+2+3... n+ (n+1)+(n+2)....

So can you tell me how will you pick the dynamic part of your formula that are P,R,T,n,a,b in the above example.

AFAIK, It will be easy if you put your formula's within the code. Yes you can do one common thing. Create a class file, that will contain a generic approach of all the formula's required by your program as methods and call them whereever required.

See below

public static class MathematicalBench
{
    public static double SimpleInterest(double principal, double rate, double time)
    {
       return (principal*rate*time)/100;
    }
}

Now call whereever required

Class A:
    private void SomeMethod1()
    {
       // Your logic 
       var interest=  MathematicalBench.SimpleInterest(128765.98,3.6,16);
    }

Another Class B:
    private void SomeNewMethod1()
    {
       // Your logic 
       var interest=  MathematicalBench.SimpleInterest(6523898,6.2,10);
    }

This would be more flexible and easy of course.

Upvotes: 0

sourabh devpura
sourabh devpura

Reputation: 625

Yes this is an good idea . But data type will make problem if you getting them from a text file . You also need good validation for that .

As per my advice you have to use XML for that .

It easy to handle and you can pick more accurate data as compare text file

Upvotes: 1

Related Questions