I am writing an app where I will give a set of tests/checks to the user through an UI such as:
LayerCount
ActiveLayerType
EffectCount
ActiveEffectType
CurrentTool
HasSelection
HasAlpha
etc
where the user is able to use them to define a custom logic tree such as:
if (LayerCount > 1)
{
if (ActiveLayerType == LayerType.Blend)
{
// #1
}
else if (ActiveEffectType == EffectType.GaussianBlur)
{
// #2
}
}
else if (CurrentTool == Tools.QuickSelect)
{
if (HasSelection)
{
// #3
}
}
Basically I am trying to define some sort of value that will return the Current Level in his custom logic in some way (let's say 1, 2, 3, and so on). Because I need to have the actions of the user interpreted differently based on the Current Level in his logic.
You could basically say that I am trying to hash a set of values based on the Current Level. But the problem is, I don't know how to get the current level to store it as a hash key. If I did, I could write something like:
var currentActionSet = ActionSetTable [GetCurrentLevel()]
and I would get a set of actions the user can perform based on the current level.
Although it would be more desirable to have these levels have fixed values instead of values starting from 1 to n, based on how they are ordered. So (ActiveEffectType == EffectType.GaussianBlur)'s branch would always return a fixed value no matter where it's in the logic tree.
So to sum up, the problems are:
How to define a current level value, preferrably fixed?
If using this current level value as key is the best approach, or if there is a better way of doing this?
Perhaps you can use bitflags and OR them together to make your hashcode?
int hash = ActiveLayerType | ActiveEffectType | CurrentTool
Then at some later point you can AND a perticular flag out again:
if( hash & LayerType.Blend == LayerType.Blend ) { ... } //will be true if the LayerType.Blend has previously been OR:ed into the hash variable
You can OR together enums of diffrent types too if you cast them to ints first, make sure that the enum bit values doesnt clash though.
This approach may or may not be practical for you application, but its something to consider :) more info here: http://msdn.microsoft.com/en-us/library/cc138362.aspx
Related
I am using .net framework in my project and I run into the problem.
I am using 7 DecisionVariables to create a decision tree. 5 of them are Continuous, 2 of them are Discrete and I am using C45Learning.
Way I am creating Decision Varibale:
Continuous
new DecisionVariable(SupportedValueType.ToString(), DecisionVariableKind.Continuous)
Discrete (in my case i created Discrete variable representing Day of month)
int PossibleValues = 30;
new DecisionVariable(SupportedValueType.ToString(), PossibleValues)
Now when I create a tree, its leaf nodes are nodes with Discrete decision variable and the output on this node is NULL, so when i run
tree.Decide(sample)
and it ends in this leaf node, it returns NULL.
Can anybody tell me what the problem is ?
When I was creating an input to create this Decision tree, I did not "use" every of this 30 possible values, only 2-3 of them. Could it be the problem ?
For example: (x variables are values of other decision variables and of course i provide more input data, not only 3 rows, but i only changed x values and only used this 3 days)
input: label:
x,x,x,x,x,1 -> Small
x,x,x,x,x,2 -> Medium
x,x,x,x,x,3 -> Big
Yes, my guess is that your tree is simply incomplete.
When using that algorithm, if I do not provide it with a comprehensive training set containing every possible combination of the input columns, then my chance of getting null leaves is much higher. However, this algorithm is known for having null paths anyway as a byproduct of its pruning process.
Check to see if other samples also return null. If they all do, then you might have an issue. If only a couple are returning NULL/unknown then it is probably simply a result of the way the tree built itself. In that case you will need to handle it with a default decision value.
I have read that there are default values you can provide for the algorithm to apply on its own, however I have never used those.
Is it more efficient to use enums instead of string arrays, performance-wise?
I decided to test a particular method IsDefined, versus checking for a match-up inside a string array. I created an object of Stopwatch to test the runtime for each one.
The code, below:
Defined an enum outside of class Main:
enum Color : byte { red, blue, green }
Inside Main:
string[] colArr = new string[] { "red", "blue", "green" };
string input = "green";
Stopwatch s1 = new Stopwatch();
int loopIterations = 0;
s1.Restart();
while (loopIterations++ < 100000000)
foreach (var blah in colArr)
if (blah == input)
break;
s1.Stop();
Console.WriteLine("Runtime for foreach loop: {0}", s1.Elapsed);
loopIterations = 0;
s1.Restart();
while (loopIterations++ < 100000000)
if (Enum.IsDefined(typeof(Color), input))
continue;
s1.Stop();
Console.WriteLine("Runtime for IsDefined method returned value: {0}", s1.Elapsed);
And my output looks like this:
Runtime for foreach loop: 00:00:01.4862817
Runtime for IsDefined method returned value: 00:00:09.3421654
Press any key to continue . . .
So I wanted to ask if - assuming the code I wrote isn't, like, stupid or something - those numbers are normal, and if they are, in what way is using enums preferable to using a string array, specifically for the kind of jobs both would?
For starters, rather than performance a big reason for using enums over strings is maintainability of the code. E.g., trying to 'find all references' to Color.red can be done with a few clicks in visual studio. Trying to find strings isn't so easy. Always typing the strings is also error-prone. Although both problems could be alleviated somewhat by using constants, it's easier to use enums.
An enum can be seen as a constant integer value, which has good performance and has benefits such as using flags (masks). Comparing an int will be faster than comparing a string, but that's not what happens here. Mostly you want to do something for a specific value and you could test if(someString == "red") versus if(someColVal == Color.red), in which case the latter should be faster.
Checking if a value exists in an enum can be slower with the Enum.IsDefined, but that function has to look up the enum-values each time in this loop.
Meanwhile the first test has a pre-defined array. For the strict comparison in performance to your first test, you could do something like:
var colvalues = Enum.GetValues(typeof(Color)).Cast<Color>().ToArray(); // or hardcode: var colvalues = new[]{Color.red, Color.blue, Color.green};
var colinput = Color.red;
while (loopIterations++ < 100000000)
foreach (var blah in colvalues)
if (blah == colinput)
break;
Although as stated, finding if a value exists in an enum is normally not its primary function (mostly it's used for checking for a specific value). However it's integer base allows for other methods to check if a value is in an expected range, such as mask-checking or >, >=, < or <=
edit Seeing the comments about user input: mostly the input would be controlled, e.g.: the user is shown a menu. In a console environment that menu could be build with the numbers of the enum.
For example, enum enum Color : byte { red = 1, blue, green }, menu
1. red
2. blue
3. green
The user input would be an integer. On the other hand if typing is required, IsDefined would prevent having to retype the values and is good for ease of use. For performance the names could be buffered with something like var colvalues = Enum.GetNames(typeof(Color)).ToArray();
The normal use for enums is to represent logical states or a limited range of options: in your example, if e.g. a product ever only comes in three colours. Using a string to represent colours in such a case has two drawbacks: you may misspell the name of a colour somewhere in your code, and get hard to track bugs; and string comparison is inherently slower than comparing enums (which is basically comparing integers).
IsDefined() uses type reflection, and thus should be slower than straight string comparison. There are cases where you want to convert enums to and from strings: usually when doing input/output such as saving or restoring configurations. That's slower, but input/output is typically dominated by the slowness of storage media and networks, so it's seldom a big deal.
I know this is a very old post, but noticed the compared code snippets for the loops are not doing the looping in a similar fashion.
As in the first loop, you let the loop break once it finds the string in the string array but in the second scenario you dont let the loop stop but rather continue if the Enum.IsDefined finds the value.
When you actually let the loop in enum scenario to break if it finds the value, the enum scenario runs much faster...
What's the best way to go about handling nulls during a binary search over a List<string> (well, it would be a List<string> if I could read all the values out beforehand)?
int previous = 0;
int direction = -1;
if (itemToCompare == null) {
previous = mid;
for (int tries = 0; tries < 2; tries++) {
mid += direction;
itemToCompare = GetItem(mid);
while (itemToCompare == null && insideInclusiveRange(min, max, mid)) {
mid += direction;
itemToCompare = GetItem(mid);
}
if (!insideInclusiveRange(min, max, mid)) {
/* Reached an endpoint without finding anything,
try the other direction. */
mid = previous;
direction = -direction;
} else if (itemToCompare != null) {
break;
}
}
}
I'm currently doing something like the above - if null is encountered, then linearly search in a direction until either non-null or beyond endpoint is encountered, if no success then repeat in other direction. In the actual code I'm getting direction from the previous comparison result, and GetItem() caches the values it retrieves. Is there an easier way, without making an intermediate list of non-null values (takes far too long for my purposes because the GetItem() function above is slow)?
I guess I'm asking if there's a smarter way to handle null values than to degrade to a linear search. In all likelihood there will only be a small percentage of nulls (1-5%), but it's possible for there to be sequences of 100s of null.
Edit - The data looks something like this
aa aaa
b bb bbb
c cc
d ddd
where each row is a separate object, and not all cells are guaranteed to be filled. The user needs to be able to search across an entire row (so that both "bb" and "bbb" would match the entire second row). Querying each object is slow enough that a linear search will not work. For the same reason, creating a new list without nulls is not really feasible.
Unless there is a reason to actually select/find a null value (not sure what that means as null is a singleton and binary search is often most desirable on unique values), consider not allowing them in the list at all.
[Previous answer: After reflecting on the question more I have decided that nulls likely have no place in the problem-space -- take bits and parts as appropriate.]
If nulls are desired, just sort the list such that null values are first (or last) and update the logic correctly -- then just make sure not to invoke a method upon any of the null values ;-)
This should have little overall impact since a sort is already required. If items are changed to null -- which sounds like an icky side-effect! -- then just "compact" the List (e.g. "remove" the null item). I would, however, just not modify the sorted list unless there is a good reason.
Binary search is only really designed/suitable for (entirely) sorted data. No point turning it into a binary-maybe-linear search.
Happy coding.
I am validating input on a form and attempting to prompt the user of improper input(s) based on the combination of controls used.
For example, I have 2 combo boxes and 3 text boxes. The 2 combo boxes must always have a value other than the first (default) value, but one of three, or two of three, or all text boxes can be filled to make the form valid.
In one such scenario I have a 6 line if statement to try to make the test easily readable:
if ((!String.Equals(ComboBoxA.SelectedValue.ToString(), DEFAULT_COMBO_A_CHOICE.ToString())
&& !String.IsNullOrEmpty(TextBoxA.Text)
&& !String.Equals(ComboBoxB.SelectedValue.ToString(), DEFAULT_COMBO_B_CHOICE.ToString()))
||
(!String.IsNullOrEmpty(TextBoxB.Text)
|| !String.IsNullOrEmpty(TextBoxC.Text)))
{
//Do Some Validation
}
I have 2 questions:
Should this type of if statement be avoided at all cost?
Would it be better to enclose this test in another method? (This would be a good choice as this validation will happen in more than one scenario)
Thanks for your input(s)!
In such a case I find it helps to move some of the logic out of the if statement and into some more meaningfully named booleans. Eg.
bool comboBoxASelected = !String.Equals(ComboBoxA.SelectedValue.ToString(), DEFAULT_COMBO_A_CHOICE.ToString());
bool comboBSelected = !String.Equals(ComboBoxB.SelectedValue.ToString(), DEFAULT_COMBO_B_CHOICE.ToString());
bool textBoxAHasContent = !String.IsNullOrEmpty(TextBoxA.Text);
bool textBoxBHasContent = !String.IsNullOrEmpty(TextBoxB.Text);
bool textBoxCHasContent = !String.IsNullOrEmpty(TextBoxC.Text);
bool primaryInformationEntered = comboBoxASelected && textBoxAHasContent && comboBSelected;
bool alternativeInformationEntered = textBoxBHasContent || textBoxCHasContent;
if (primaryInformationEntered || alternativeInformationEntered)
{
//Do Some Validation
}
Obviously, name the combo and text boxes to reflect their actual content. When someone has to work their way through the logic several months down the line they'll thank you.
a) Doesn't have to necesarily be avoided at all costs. The code works. But it is certainly messy, confusing and I would say could be difficult to maintain.
b) Yes. Give it a relevant name so that the code reader knows what is going on there.
I personally wouldn't have a big issue with code like this. (Your last set of parentheses seem unnecessary.)
Generally, I'd like to keep my if statements simpler. But all your conditions are simple ones. If you really need to test that many tests, then I'd keep it like it is.
It is not very readable yes. But you can shorten it:
!String.Equals(ComboBoxA.SelectedValue.ToString(), DEFAULT_COMBO_A_CHOICE.ToString()
could also be written as:
ComboBoxA.SelectedValue.ToString()!=DEFAULT_COMBO_A_CHOICE
I presume DEFAULT_COMBO_A_CHOICE is already of string to ToString si superflous.
also the parenthese around
(!String.IsNullOrEmpty(TextBoxB.Text)
|| !String.IsNullOrEmpty(TextBoxC.Text))
are not necessary.
IMO such conditions should be avoided (though not at all costs). They are very difficult to read an maintain.
There are several ways of doing that
Try and group the conditions according to the behavior they represent. For example
if (OrderDetailsSelected() && ShippingAddressProvided() )
{
This way you can also avoid the duplication of the conditions within your form.
Secondly, you can use the Boolean Algebra to simplify the expression and
Use Extract Method refactoring to move conditions, which are difficult to read in functions to avoid duplication and make them more readable.
For ex. The condition
String.Equals(ComboBoxB.SelectedValue.ToString(), DEFAULT_COMBO_B_CHOICE.ToString())
can be extracted into a function
private bool IsDefaultA() { return ... }
Is there a better way for writing a condition with a large number of AND checks than a large IF statement in terms of code clarity?
Eg I currently need to make a field on screen mandatory if other fields do not meet certain requirements. At the moment I have an IF statement which runs over 30 LOC, and this just doesn't seem right.
if(!(field1 == field2 &&
field3 == field4 &&
field5 == field6 &&
.
.
.
field100 == field101))
{
// Perform operations
}
Is the solution simply to break these down into smaller chunks and assign the results to a smaller number of boolean variables? What is the best way for making the code more readable?
Thanks
I would consider building up rules, in predicate form:
bool FieldIsValid() { // condition }
bool SomethingElseHappened() { // condition }
// etc
Then, I would create myself a list of these predicates:
IList<Func<bool>> validConditions = new List<Func<bool>> {
FieldIsValid,
SomethingElseHappend,
// etc
};
Finally, I would write the condition to bring forward the conditions:
if(validConditions.All(c => c())
{
// Perform operations
}
The right approach will vary depending upon details you haven't provided. If the items to be compared can be selected by some sort of index (a numeric counter, list of field identifiers, etc.) you are probably best off doing that. For example, something like:
Ok = True
For Each fld as KeyValuePair(Of Control, String) in CheckFields
If fld.FormField.Text fld.RequiredValue Then
OK = False
Exit For
End If
Next
Constructing the list of controls and strings may be a slight nuisance, but there are reasonable ways of doing it.
Personally, I feel that breaking this into chunks will just make the overall statement less clear. It's going to make the code longer, not more concise.
I would probably refactor this check into a method on the class, so you can reuse it as needed, and test it in a single place. However, I'd most likely leave the check written as you have it - one if statement with lots of conditions, one per line.
You could refactor your conditional into a separate function, and also use De Morgan's Laws to simplify your logic slightly.
Also - are your variables really all called fieldN?
Part of the problem is you are mixing meta data and logic.
WHICH Questions are required(/must be equal/min length/etc) is meta data.
Verifying that each field meets it's requirements is program logic.
The list of requirements (and the fields that apply too) should all be stored somewhere else, not inside of a large if statement.
Then your verification logic reads the list, loops through it, and keeps a running total. If ANY field fails, you need to alert the user.
It may be useful to begin using the Workflow Engine for C#. It was specifically designed to help graphically lay out these sorts of complex decision algorithms.
Windows WorkFlow Foundation
The first thing I'd change for legibility is to remove the almost hidden negation by inverting the statement (by using De Morgan's Laws):
if ( field1 != field2 || field3 != field4 .... etc )
{
// Perform operations
}
Although using a series of && rather than || does have some slight performance improvement, I feel the lack of readability with the original code is worth the change.
If performance were an issue, you could break the statements into a series of if-statements, but that's getting to be a mess by then!
Is there some other relationship between all the variables you're comparing which you can exploit?
For example, are they all the members of two classes?
If so, and provided your performance requirements don't preclude this, you can scrape references to them all into a List or array, and then compare them in a loop. Sometimes you can do this at object construction, rather than for every comparison.
It seems to me that the real problem is somewhere else in the architecture rather than in the if() statement - of course, that doesn't mean it can easily be fixed, I appreciate that.
Isn't this what arrays are basically for?
Instead of having 100 variables named fieldn, create an array of 100 values.
Then you can have a function to loop combinations in the array and return true or false if the condition matches.