I have an object model that I need the user to be able to create a formula based on, and also use some built-in functions. For example:
AddWorkDays(MyObject.StartDate, 3)
MyObject has various properties that the user may access. We may also need to do some If/Then statements. The users are very familiar with Excel formulas, because that is how they currently do their work.
I see two possible options:
create my own parser using one of the many available C# Libraries
Adapt an Excel-based parser to be context aware of my objects.
The issue with option 1 is I don't want to re-invent the wheel. I would expect someone has already built a parser that can handle basic functions and math operations and is context aware based on class(es) passed in. I can't seem to find something like this.
Option 2 would allow the user to re-use their existing Excel knowledge to build formulas like:
=if(MyObject.Type = "A", AddWorkDays(MyObject.StartDate, 3), AddWorkDays(MyObject.StartDate, 5)
I see XLParser is advertised as being great for parsing Excel formulas, but it seems I would need to add-on the Context-aware part for reading and validating properties on MyObject.
Any experience, examples, warnings, etc. on how to proceed are welcome
I solved this issue by using the FLEE library: https://github.com/mparlak/Flee
It supports "Context" where you can define variables that should be in context. Out of the box it supports regular syntax for things like addition, subtraction, and even a basic IF statement. It is easily extensible to add your own functions. I made it Excel-like by defining some of the common functions: AND, OR, MIN, MAX. This was less than 100 lines of code to do.
I use it to process relatively large data sets (200,000 items with 5 formulas for each item) and it processes in under 10 seconds if used correctly.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I'm coming to C# from Python & JS and am enjoying it thoroughly so far. One of the quirks however is that it seems a lot of steps need to be taken to do some simple things. For instance if I have a 2D array and want to simply print out a 2D matrix to the console, this will require more code rather than calling a simple method like in Python. This is because printing the array will print the object type rather than its inner values. I've read one book so far and already know about method overriding, such as overriding .ToString() to do this, and know how to do this, so my question is more "what is the best practice to create and use your own global methods to do common tasks?" Or do any libraries exist that may already include many simple featurs like this?
What I'm looking to do is one of two things, and I'm curious which might be considered "better practice" -
1) Array is an object that has a lot of useful methods for manipulating arrays, but I'd like it if there was a method such as Array.PrintArray(arr) which would print the array and any inner arrays to the console. Since it seems there's no native method to do this, I'd like to write my own Array.PrintArray(arr) and make it available globally to all projects. Doing this seems like I'd need to extend the native Array object, and use this extension globally. I'm not sure how to do that, or if it's even a good idea to do that.
2) Alternatively if the above isn't good practice, I'd like to write my own helper object, lets call it "HelperSelf" with a list of my own methods, and make this helper object available globally to all projects. Eg, I could define a method HelperSelf.PrintArray so that I could type HelperSelf.PrintArray(arr) in any project in C# to print that array to the console in a way I define it.
So my question is twofold -
1) What is the best way to centrally define a way to do something via my own "helper" methods that I code so that the entire C# namespace has access to these helper methods?
2) Is doing something like this considered "best practice" or useful in C#? Does anyone else do something like this to print n-dimensional arrays to the console without having to manually write longer lines of code every time they wish to do so? Or is doing something like this considered highly unusual and it's better we just stick to writing multiple lines of code each time?
The printing n-dimensional array to console is an example of just one thing I want to do. In reality I'd like to code probably tens, or even 100+ of my own "helper" functions which I think would make things in C# much simpler coming from a Python background.
PS: The reason I want to use C# instead of Python is for projects that are better suited for C#, such as game development, systems operations, large scale projects where I find typing to be an incredibly useful feature, etc.
This is perhaps one of the reasons why languages like php, python etc get a bad rap, because they might have lots of these "semi useless" things built in. I don't personally regard "printing a 2d array to the console" as a particularly useful thing for the .net framework to contain because I don't recall, in the last 10 years, printing to the console in anything more than a scrappy test app of dotnetfiddle.com - none of the enterprise systems I work on write anything to the console though they can be configured to I suppose; they use NLog and custom loggers to write to Azure table storage etc but I could drop a console connector in there if I wanted to. Tend to just look up the logging output in Azure- we have a visualisation tool for it even
1)
make a static method or a static class that has your helpers, possibly in another project so you can import it and reference it. If you make the most amazing set of console drawing classes you can even package it as a NuGet offering and make it available to the world but on the simple level putting it in a NuGet serve (and you can easily host your own if your library isn't likely to find widespread use) means it's a few clicks to get it into your next project. Here's a simple one liner to flatten a 2d array Into a csv string for printing to the console, for example:
public static PrintArray(object [][] a){
var s = string.Join("\r\n", a.Select(inner => string.Join(",", inner));
Console.WriteLine(s);
}
Once this is written inside your helper class you can import the helper namespace to anywhere in your project and call it. You could even turn it into an extension method so that all arrays gain then ability to just say somearray.PrintArray rather than PrintHelper.PrintArray(x) though it wouldn't give expected results on arrays of other dimensions than 2
2)
whether it's unusual largely depend on your context. As noted for me it would be highly unusual to ever touch the console but if one day I went somewhere where there was some legacy cgi app that they couldn't replace with something better then it might well be that every project I wrote would have to output csv data in a very particular format to the console so the other app could consume it. It's not easy to say an answer that addresses this in all possible contexts but I do truly appreciate that Microsoft strive to keep the framework relatively bloat free, and resist adding methods that to a large extent would only be of interest to a narrow section of the population, instead preferring to focus on providing ways to make very generically capable methods to let you build the specific you want.
LINQ is one great example of this and a testament to its success in this regard is that once people discover it they tend to view it as a hammer and every problem is a nail; it ends up getting abused for all sorts of things, sometimes inappropriately - as generic, adaptable solutions often do. There is no question that it makes your developer life easier by cutting down the number of loops you have to write though. Once upon a time finding the max int in an array or calculating whether an array had a person whose last name was smith looked like:
int m = int.MinValue;
foreach(int x in array)
if(x>m)
x=m;
bool found = false;
foreach(var p in personarray)
if(p.LastName == "Smith"){
found = true;
break;
}
Now it's:
intarray.Max();
personarray.Any(p=>p.LastName == "Smith");
I do look at c# as more like a box full of Lego bricks where you build your own castles, where other languages have a lot of prebuilt castles floating around in with all the individual bricks. LINQ is one example of a fabulous prebuilt castle that does all sorts of wonderful things, but the way it's been able to be worked into the framework means it's still super generic and can be imported to create a set of extensions across all your arrays, lists, and other data containers, and in and of itself it doesn't do anything particular other than visit every element of a sequence and call a bit of code you provide so you're still tasked with making it specifically useful by crafting that code
The suggestion to look at NuGet.org is a good one; everyone has written everything. Your desire to write hundreds of helper classes may well have already been filled. I tend to find when it comes down to the brass tacks of actually doing my work, my job, I don't spend a lot of time writing helper classes because a lot of it is either on NuGet or turns out unnecessary because every project is different enough that curating a massive collection of helpers isn't actually helpful. One of the go to NuGet libraries that nearly every project I work on uses is Newtonsoft's JSON - interesting that it's an order of magnitude more downloaded than the rest of the top 100 (https://www.nuget.org/stats/packages) and that in itself is an indicator that the framework is fairly comprehensive in its ability to provide for most things you want to do without needing extra help. Coupled with the earlier points about it being relatively bloat free is probably an indicator of how well thought out it is in terms of "what do the majority of commercial applications need the framework to contain?"
I did also write a simple emailer helper some years ago that has found its way into many projects but by and large the company projects are bereft of suites of helpers created by our team, and have their own micro custom ones so don't spend a lot of time creating hundreds of them.. maybe let the work drive that one and only put in the library something that has been pasted into 3+ projects
You can use Generic and extension methods for that. For example, you can define Print extension method like this
public static class ArrayExtensions {
public static void Print<T> (this IEnumerable<T> items) {
foreach (var item in items) {
Console.WriteLine (item);
}
}
}
and the usage like this
var numbers = new[] { 1, 2, 3, 4, 5 };
numbers.Print();
var names = new string[] { "van", "ngan" };
names.Print();
We are developing a product that will be deployed for a number of clients. In an area of this product, we need to execute some formulas. The problem is that this formulas can be different for each client. So we need to have a good architecture that can 'execute code dynamically'
The application is a web application hosted on sharepoint 2010 (thereby using .net 3.5)
A Simplified example:
I have class MyClassA with two numeric properties PropA and PropB
For one client the formula is PropA + PropB. For the other it is PropA-PropB.
This is just a simplified example as the formula is more complex than this.
I need to have a way that client A we can set PropA+PropB perhaps in an XMl file or database.
I would then load the code dynamically?
Does this make sense? Has anyone implement similar scenario in a production environment please?
I have found that the following article describes a similar situation but I do not know whether it is 100% reliable for a production environment:
http://west-wind.com/presentations/dynamicCode/DynamicCode.htm
I have also found that IronPython can also solve a similar problem but I cannot understand how I would use my ClassA with IronPython.
Any assistance would be greately appreciated.
Update ...
Thanks everyone for the detailed feedback. It was a very constructive exercise. I have reviewed the different approaches and it seems very likely that we will go ahead with the nCalc approach. nCalc seems to be a wonderful tool and I am already loving the technology :)
Thank you all!!
Look into nCalc.
You could store your calculations in a database field then simply execute them on demand. Pretty simple and powerful. We are using this in a multi-tenant environment to help with similar types of customization.
I'm just proposing this because I don't know the problem very well but the idea could be a Dll for each formula (so you can handle the code as you wish, with normal C# functionalities instead of an uncomfortable xml file).
With MEF you can inject dll into your code (you just have to upload those when you develop a new one, no need to recompile the exe file) and have a different formula for each client.
This is my idea because it looks like a perfect example for Strategy pattern
Do you have a fixed set of formulas, or does the client have the capacity to dynamically type those in, i.e. as for a calculator?
In the first case, I'd recommend the following: set of C# delegates, which get called/call each other in a particular order, and (a) Dictionary(ies) of closures which fit the delegates. The closures would then be assigned to the delegates based on your predefined conditions.
In the alternative case, I wouldn't compile .NET code based on what the client types in, since that (unless preempted) represents a server-side security risk. I would implement/adapt a simple parser for expressions that you're expecting.
P.S. nCalc sugguested by Chris Lively is definitely a viable option for this kind of task, and is better than directly using delegates if you have tons and tons of formulas that you don't want to keep in memory.
ClassA with Ironpython?
Keep it simple
Run through the classA instance for each member (maybe a custom attribute to mark up the ones you want to use in the calc) and end up with name=value pair which by some unfortunate coincidence looks like an assignment
e.g
PropA = 100
PropB = 200
Prepend that to your python script
PropAPropB = PropA + PropB
Execute the script which is the assignments and the calculation
Then it's basically
ClassB.PropAPropB = ipCalc.Eval("PropAPropB");
You can start getting real clever with it, but a methods to get the inputs from an instance and one the evaluatios the result of the calc and sets teh properties.
Bob's your mother's sister's brother...
I am working on an ASP.NET project that is relatively simple except for one requirement which requires custom questionnaires be attached to specific types of tasks. These questionnaires need to be customized regularly and no development, within the app itself, should be needed add questionnaires. The questionnaires currently do not require an editing tool and can be done by uploading a template, changing something in a DB, whatever. They can be stored in any format and the resulting output needs to be captured to be edited or viewed later.
The types of questions in the questionnaire could be:
Selections (select one from a list)
Input (text, integers, dates, etc)
Yes/No
The ability to display questions based on answers from other questions. For example if they answer yes to question X, display question Y else display question Z. Need to be able to apply data validation such as required fields, ranges, etc on questions (could all be probably capture by basic regex).
The simplest break down would be:
Create a new event.
Based on the type of event display a specific questionnaire.
Questionnaires can change over time but they can be considered as new version each time and data will always be related to a specific version and not need to be migrated to updated versions.
The questionnaire output (data elements and a final calculated value) must be captured.
XML output (or any other format) of data elements entered.
The optimal (unicorn) scenario would be to have a basic template in XML or something that a user can learn to create easily and it would be stored and versioned in a DB. When a user makes a new event, the app would fetch the appropriate template which would display the questionnaire to the user. The user would fill it out and the output would be posted as some type of output (again XML would be nice but not required). That output would be attached to the event. Done.
Are there any .NET compatible tools/libraries that I could leverage to accomplish this? InfoPath seems like a tool that might be of use but I have almost zero experience with it so I am not sure about its constraints / implementation and if it is just overkill. The solution needs to be contained within the ASP.NET application. An external editor tool for creating templates would be ok but the templates must be viewable and editable on the web with no constraints to the user.
Can anyone provide examples of this being done or hints on how you might have tackled this?
Since the application is relatively easy to create other than this one feature, I would rather not spend 80% of my time trying to implement the custom questionnaire functionality and spend more time on the problem the application is trying to solve.
Tech available: ASP.NET, Silverlight, SQL Server
I would suggest having a look at a dot net nuke implementation, I am sure there should be a lot of viable options (if not all free).
DotNetNuke
Have a look at the Forge to see free plugins
Consider evaluating SurveyMaster at CodePlex. It's licensed under Microsoft Public License (Ms-PL), and you can modify its source for your needs.
I write code in isolation, that is I work for myself. I need some advice on how you might implement the following functionality or if there are some tools that already exist to help make this task easier to accomplish.
I have a scenario (C# application) in which I would like the user to be able to enter conditional rules which will then be used elsewhere in the program for various calculations.
As a simple example let's say we have a TimeRequiredForJob property and we need to calculate this in the program based upon the users rules. A simple rule might be
TimeRequiredForJob = 200 Balloons multiplied by 5 min each, or
TimeRequiredForJob = 20% of HoursInAfternoon
I am guessing its pretty hard to see what I am looking for so maybe the following image will help:
This is from DevExpress XtraGrid and it allows a user to filter data displayed in the grid based upon the users custom filter rules. I would like to implement something similar but be able to save the rules to a database and use those rules later in the application.
Any suggestions or tips welcome.
[Late Edit]
Actually I am getting some good information from this question but any additional information will be appreciated.
Forgetting about the GUI for a second, you will need to first need to build some kind of rule evaluation processor.
You may find this article on building an Evaluation Engine helpful. It describes processing text expressions into a form that can be evaluated.
Once you have a way of representing these rules (either as an object structure or as text expressions) the task of building a GUI to suit your specific requirements will become easier.
I need to allow my users to be able to define formulas which will calculate values based on data. For example
//Example 1
return GetMonetaryAmountFromDatabase("Amount due") * 1.2;
//Example 2
return GetMonetaryAmountFromDatabase("Amount due") * GetFactorFromDatabase("Discount");
I will need to allow / * + - operations, also to assign local variables and execute IF statements, like so
var amountDue = GetMonetaryAmountFromDatabase("Amount due");
if (amountDue > 100000) return amountDue * 0.75;
if (amountDue > 50000) return amountDue * 0.9;
return amountDue;
The scenario is complicated because I have the following structure..
Customer (a few hundred)
Configuration (about 10 per customer)
Item (about 10,000 per customer configuration)
So I will perform a 3 level loop. At each "Configuration" level I will start a DB transaction and compile the forumlas, each "Item" will use the same transaction + compiled formulas (there are about 20 formulas per configuration, each item will use all of them).
This further complicates things because I can't just use the compiler services as it would result in continued memory usage growth. I can't use a new AppDomain per each "Configuration" loop level because some of the references I need to pass cannot be marshalled.
Any suggestions?
--Update--
This is what I went with, thanks!
http://www.codeproject.com/Articles/53611/Embedding-IronPython-in-a-C-Application
Iron Python Allows you to embed a scripting engine into your application. There are many other solutions. In fact, you can google something like "C# embedded scripting" and find a whole bunch of options. Some are easier than others to integrate, and some are easier than others to code up the scripts.
Of course, there is always VBA. But that's just downright ugly.
You could create a simple class at runtime, just by writing your logic into a string or the like, compile it, run it and make it return the calculations you need. This article shows you how to access the compiler from runtime: http://www.codeproject.com/KB/cs/codecompilation.aspx
I faced a similar problem a few years ago. I had a web app with moderate traffic that needed to allow equations, and it needed similar features to yours, and it had to be fast. I went through several ideas.
The first solution involved adding calculated columns to our database. Our tables for the app store the properties in columns (e.g., there's a column for Amount Due, another Discount, etc.). If the user typed in a formula like PropertyA * 2, the code would alter the underlying table to have a new calculated column. It's messy as far as adding and removing columns. It does have a few advantages though: the database (SQL Server) was really fast at doing the calculations; the database handled a lot of error detection for us; and I could pretend that the calculated values were the same as the non-calculated values, which meant that I didn't have to modify any existing code that worked with the non-calculated values.
That worked for a while until we needed the ability for a formula to reference another formula, and SQL Server doesn't allow that. So I switched to a scripting engine. IronPython wasn't very mature back then, so I chose another engine... I can't remember which one right now. Anyway, it was easy to write, but it was a little slow. Not a lot, maybe a few milliseconds per query, but for a web app the time really added up over all the requests.
That was when I decided to write my own parser for the formulas. That is, I have a PlusToken class to add two values, an ItemToken class that corresponds to GetValue("Discount"), etc. When the user enters a new formula, a validator parses the formula, makes sure it's valid (things like, did they reference a column that doesn't exist?), and stores it in a semi-compiled form that's easy to parse later. When the user requests a calculated value, a parser reads the formula, parses it, figures out what data is needed from the database, and computes the final answer. It took a fair amount of work up front, but it works well and it's really fast. Here's what I learned:
If the user enters a formula that leads to a cycle in the formulas, and you try to compute the value of the formula, you'll run out of stack space. If you're running this on a web app, the entire web server will stop working until you reset it. So it's important to detect cycles at the validation stage.
If you have more than a couple formulas, aggregate all the database calls in one place, then request all the data at once. Much faster.
Users will enter wacky stuff into formulas. A parser that provides useful error messages will save a lot of headaches later on.
If the custom scripts don't get more complex than the ones that you show above, I would agree with Sylvestre: Create your own parser, make a tree and do the logic yourself. You can generate a .Net expression tree or just go through the Syntax tree yourself and make the operations within your own code (Antlr below will help you generate such code).
Then you are in complete control of your references, you are always within C#, so you don't need to worry about memory management (any more than you would normally do) etc. IMO Antlr is the best tool for doing this in C# . You get examples from the site for little languages, like your scenario.
But... if this is really just a beginning and at the end you need almost full power of a proper scripting language, you would need to go into embedding a scripting language to your system. With your numbers, you will have a problem with performance, memory management and probably references as you noted. There are several approaches, but I cannot really give one recommendation for your scenario: I've never done it in such a scale.
You could build two base classes UnaryOperator (if, square, root...) and BinaryOperator (+ - / *) and build a tree from the expression. Then evaluate the tree for each item.