Why is the cylcomatic complexity of this function 12? - c#

I have a (C#) function that checks four sets of conditions and returns a bool. If any of them are true, it returns true. I'm sure I could simplify the logic but I want it to be fairly readable.
The CodeMaid extension in Visual Studios and tells me the cylomatic complexity of the function is 12. I looked it up and the cylomatic complexity is
the number of independent paths through the source code
I don't understand why it's 12. I can think of it two ways, either the cyclomatic complexity should be 2, because it always goes through the same path but could return either a true or a false. Or could understand if it was 16, because the four booleans or'd together at the end could each be true or false, 2*2*2*2 = 16.
Can someone tell me why its 12? Maybe even show a diagram so I can visualize the different paths?
public bool FitsCheckBoxCriteria(TaskClass tasks)
{
// note: bool == true/false comparisons mean you don't have to cast 'bool?' as bool
// if neither checkboxes are checked, show everything
bool showEverything = NoShutDownRequiredCheckBox.IsChecked == false &&
ActiveRequiredCheckBox.IsChecked == false;
// if both are checked, only show active non-shutdown tasks
bool showActiveNonShutdown = ActiveRequiredCheckBox.IsChecked == true &&
tasks.Active == "YES" &&
NoShutDownRequiredCheckBox.IsChecked == true &&
tasks.ShutdownRequired == "NO";
// if active is checked but shudown isn't, display all active
bool showActive = ActiveRequiredCheckBox.IsChecked == true &&
tasks.Active == "YES" &&
NoShutDownRequiredCheckBox.IsChecked == false;
// if non-shutdown is checked but active isn't, display all non-shutdown tasks
bool showNonShutdown = NoShutDownRequiredCheckBox.IsChecked == true &&
tasks.ShutdownRequired == "NO" &&
ActiveRequiredCheckBox.IsChecked == false;
return showEverything || showActiveNonShutdown || showActive || showNonShutdown;
}
Thanks in advance.
Edit:
I changed it to this. assigning local variables for the checkbox conditions didn't have any effect, but creating booleans out of the "YES"/"NO" cranked up the complexity to 14, which I think I understand.
public bool FitsCheckBoxCriteria(LubeTask tasks)
{
bool noShutdownReqChecked = (bool)NoShutDownRequiredCheckBox.IsChecked;
bool activeChecked = (bool)ActiveRequiredCheckBox.IsChecked;
bool active = tasks.Active == "YES" ? true : false;
bool shutdownReq = tasks.ShutdownRequired == "YES" ? true : false;
// if neither checkboxes are checked, show everything
bool showEverything = !noShutdownReqChecked && !activeChecked;
// if both are checked, only show activeChecked non-shutdown tasks
bool showActiveNonShutdown = activeChecked && noShutdownReqChecked && active && !shutdownReq;
// if activeChecked is checked but shudown isn't, display all activeChecked
bool showActive = activeChecked && !noShutdownReqChecked && active;
// if non-shutdown is chceked but activeChecked isn't, display all non-shutdown tasks
bool showNonShutdown = noShutdownReqChecked && !activeChecked && !shutdownReq;
return showEverything || showActiveNonShutdown || showActive || showNonShutdown;
}

The key is in "independent paths".
I'm going to rewrite your code to shorten it so we can discuss it.
public bool FitsCheckBoxCriteria(TaskClass tasks)
{
bool E1 = A1 && A2;
bool E2 = B1 && B2 && B3 && B4;
bool E3 = C1 && C2 && C3;
bool E4 = D1 && D2 && D3;
return E1 || E2 || E3 || E4;
}
The Cyclomatic complexity is the number of independent paths. This is not the total possible number of return values (2).
The && operator and the || operator are short circuit operations; if A1 is false, A2 is not evaluated. Similarly, if E1 is true, E2 is not evaluated.
If you replace all the &&s with & and all the ||s with | in the code above, the cyclomatic complexity is 1, because there is only one path through the code.
(This wouldn't make it better code though).
As it is, there are 72 possible paths...
A1, B1, C1, D1, E1 are evaluated; the others are not.
A1, A2, B1, C1, D1, E1 are evaluated; the others are not.
A1, B1, B2, C1, D1, E1 are evaluated; the others are not.
A1, A2, B1, B2, C1, D1, E1 are evaluated; the others are not.
etc...
But path 4 doesn't contain any new code that isn't already on the previous paths. And this is the definition of "independent paths" - each path must include new code.
So in this example, you can count the code by hand as follows:
1 + the number of short circuit operators in this code (11) = 12.
Wikipedia has an excellent in depth explanation.

This is just a guess, but I think the assignments are +2 each (if =true/else =false) and then +1 for each possible exit condition in the return statement. So it might unwind into something like:
bool showEverything = false;
if (...) { showEverything = true; } +1
else { showEverything = false; } +1
bool showActiveNonShutdown = ... +2 if/else
bool showActive = ... +2 if/else
bool showNonShutdown = ... +2 if/else
if (showEverything) {...} +1
else if (showActiveNonShutdown) {...} +1
else if (showActive) {...} +1
else if (showNonShutdown) {...} +1
else {false}

C# uses short-circuit evaluation which means that if there is an x && y expression y is evaluated only if it is necessary, more precisely, if x is true. This means that result = x && y; has two independent execution paths: (1) if x is false then only x is evaluated and result gets false value (without evaluating y) but (2) if x is true y is evaluated as well and result gets the evaluation result of y. This means that every && and || operator increases the cyclomatic complexity and in the first example there are 8 && and 3 || operators so the cyclomatic complexity of the method is 12.

Related

how to get 2 false Boolean and return true as result

In math, we have -1 * -1 = 1. When 2 negatives multiplies together, we get a positive.
However in C# bool, I am not able to find a way to do so.
int i = -1
int j = -1
bool bi = i>0
bool bj = j>0
Console.writeLine (bi)
Console.writeLine (bj)
Console.writeLine (bi && bj)
result:
false
false
false
obviously, the && is the not the right operator.
Which operator allows me to have 2 Boolean when both are false, returning true
i.e.
Console.Writeline (false false)
result true
The closest to your logic is using negated XOR:
! (bi ^ bj);
This way you'd get something like:
1 * 1 = 1
-1 * 1 = -1
1 * -1 = -1
Also you could use simple comparison operator ==:
bi == bj;
Which operator allows me to have 2 Boolean when both are false,
returning true
If you want to check two values are equal (e.g. both are true or both are false) then == (the equality operator) is your best bet.
var bob = true == true;
var bob2 = false == false;
Both bob and bob2 will be true.
This is perfect for your problem since you want to know if both numbers are negative or both numbers are positive (since in either of those scenarios, multiplying them will result in a positive number).
Console.Writeline(bi == false && bj == false) or for short (!bi && !bj)

Datetime usage with in <> operators

I have a datetime definition that I do not know how to use of. What exactly is the expression between the <> signs? it returns Boolean but how?
bool x= DateTime.Now.AddDays(20) <DateTime.Now && DateTime.Now.AddDays(10)> DateTime.Now;
Format it differently and it will be easy to see that it's two less than/greater than signs:
bool x = DateTime.Now.AddDays(20) < DateTime.Now
&& DateTime.Now.AddDays(10) > DateTime.Now;
bool x = DateTime.Now.AddDays(20) < DateTime.Now //(1)
&& DateTime.Now.AddDays(10) > DateTime.Now; //(2)
To English:
(1): Is (Today + 20 days) smaller than Today?
// We have False
(2): Is (Today + 10 days) greater than Today?
// We have True
And Finally (1) && (2) will return your result x
// We have x = True && False = False
What exactly is the expression between the <> signs? it returns Boolean but how?
As already mentioned in the code that you posted < and > and && are operators and not tags
the first < is a "less than" relational operator
the last > is a "greater than" relational operator
These operators compare the operands at each side of the operator and return true or false.
the middle operator && is called The conditional-AND operator and it
performs a logical-AND of its bool operands
This is why the whole statement returns bool

Short circuit condition fail

I've a bit problem with a short circuit condition, what I need to do is check if an array have almost 2 indexes or a string is equal to a certain value, to recreate the problem here, suppose this:
string[] favItem = new string[] { "hello", "world", "test", "foo" };
string temp = "hello";
var itemToRemove = temp.Split(',');
foreach(var fav in favItem)
{
if(fav == "foo" || (itemToRemove.Length > 1 & fav == itemToRemove[0] || fav == itemToRemove[1]))
{
//do something
}
}
so essentially I need to compare fav with a default value, if this fail, I need to check if the itemToRemove array have almost 2 indexes, if yes I need to compare the fav value in iteration, with the two indexes of itemToRemove.
Now suppose that in itemToRemove there is only one index, I'm not able to exit from this:
(itemToRemove.Length > 1 & fav == itemToRemove[0] || fav == itemToRemove[1])
in particular with & I'm trying to exit from the condition if the indexes aren't two.
In the debug mode I can see the false value with the breakpoint, but I don't understand why the code fall to:
OutOfRangeException
with itemToRemove[1] when should be leave the condition.
What am I doing wrong?
Your code has two problems.
First, the short-circuiting boolean "and" operator is &&. & is the bitwise and operator, and does not short circuit.
Secondly, && has a higher precedence than ||, so you need to group the second || together like this (itemToRemove.Length > 1 && (fav == itemToRemove[0] || fav == itemToRemove[1])). The rule of thumb to remember precedence is that and is like multiplication 0 && 1 = 0, while or is like addition 0 || 1 = 1.
Short circuit is && not &.

Evaluate condition irrespective of first outcome

I know this is probably a newbie question, however I need to get a recommendation for the design of this.
I need to evaluate the result of a set of conditions and they must be evaluated irrespective of the outcome of a preceding condition. This brings the case of using regular OR(|) or short-circuit evaluation using ||.
Below is the code that I need to make a design decision about, however the end goal is to be able to evaluate or condition regardless.
private bool checkExistingBPNInSession()
{
var exDirectors = (List<ViewModels.NewContact>)Session["NewDirectorDetails"];
var exTaxConsultant=(List<ViewModels.NewContact>)Session[Resources.Global.NewTaxConsultantDetails];
var exTaRep = (List<ViewModels.NewContact>)Session["NewTaxRepresentativeDetails"];
if (exDirectors.Count() != 0 || exTaRep.Count() != 0 || exTaxConsultant.Count() != 0)
{
var QueryCheckDir = (from x in exDirectors where x.BPN==txtBusinessPartnerIdNumber.Text select x.BPN).ToList();
var QueryCheckTaxConsultant = (from x in exTaxConsultant where x.BPN == txtBusinessPartnerIdNumber.Text select x.BPN).ToList();
var QueryCheckTaxRep = (from x in exTaRep where x.BPN == txtBusinessPartnerIdNumber.Text select x.BPN).ToList();
if (QueryCheckDir.Count() > 0 || QueryCheckTaxConsultant.Count() > 0 || QueryCheckTaxRep.Count() > 0)
{
return true;
}
else
{
return false;
}
}
return false;
}
These parts here have to be evaluated:
exDirectors.Count() != 0 || exTaRep.Count() != 0 || exTaxConsultant.Count() != 0
and this also
QueryCheckDir.Count() > 0 || QueryCheckTaxConsultant.Count() > 0 || QueryCheckTaxRep.Count() > 0
Please, I am seeking the best recommendations.
Thanks guys.
If you want an evaluation done, no matter what, you should use the
|-operator - this will evaluate every condition even if the outcome of the final expression would not change (contrary to ||-operator)
Here is a simple demo using dotnetfiddle

How does C# evaluates AND OR expression with no brackets

not sure if this make sense at all
im trying to understand how C# process the following logic
false && true || false
false || true && false
basically i'm trying to find out how C# evaluate these expression when there is no parentheses .
&& has a higher precedence than || so it's evaluated first. Effectively, they're equivalent to:
false && true || false => (false && true) || false => false
false || true && false => false || (true && false) => false
If you're unsure, use the parentheses. They have no real negative impact and anything that makes code more readable is generally a good thing.
Perhaps a better example (so that the results are different) would have been:
true && false || false => (true && false) || false => false
true || false && false => true || (false && false) => true
The compiler figures it out because the standard specifies operator precedence.
That said, if an expression requires you to think for more than a second about what is happening in what sequence... use parentheses to make it clear =)
C# Operators shows operator precedence:
false && true || false = (false && true) || false = false
false || true && false = false || (true && false) = false
&& (logical AND) has higher precedence than || (logical OR)
NOTE: it is good practice (some might say best practice) to always use parentheses to group logical expressions, so that the intention is unambiguous...
Everyone said about the operator precedence and the reference tables where you can look that up. But I'd like to give a hint how to remember it. If you think of false as of 0 and of true as of 1 then && is like multiplication and || is like addition (they are actually called logical multiplication and logical addition). The precedence relationship is the same: multiplication is higher then addition. It works the same way:
0 * 0 == 0 | false && false == false
0 * 1 == 0 | false && true == false
1 * 0 == 0 | true && false == false
1 * 1 == 1 | true && true == true
0 + 0 == 0 | false || false == false
0 + 1 == 1 | false || true == true
1 + 0 == 1 | true || false == true
1 + 1 == 1* | true || true == true
(*) it's actually 2 capped at 1
And normally, when in doubt, use parenthesis.
The operators will be evaluated in order of operator precedence.
So, basically, AND before ORs. Your examples are the same as:
(false && true) || false
false || (true && false)
Most importantly... C# uses short circuit operators. So that entire thing is false
link text
operator precedence
short circuit evaluation
parenthesis
left to right.
The the AND operator has higher precedence than the OR operator (see http://msdn.microsoft.com/en-us/library/6a71f45d.aspx). Meaning && is always evaluated first.
Thus x && y || z is understood to be (x && y) || z.
And a || b && c is understood to be a || (b && c).

Categories