Reputation: 13
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
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:
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"/>
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
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
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