say I have an if statement as such
if(condition1 || condition2 || condition3)
{
//do something
}
Is it possible to find out which of the 3 conditions was true when we enter the loop?
Yes, you can check each one individually with something like:
if(condition1 || condition2 || condition3) {
if (condition1) { doSomethingOne(); }
if (condition2) { doSomethingTwo(); }
if (condition3) { doSomethingThree(); }
doSomethingCommon();
}
assuming of course that the conditions aren't likely to change in the interim (such as with threading, interrupts or memory-mapped I/O, for example).
No. You'll have to do something like:
if(condition1 || condition2 || condition3)
{
if (condition1) {
}
if (condition2) {
}
if (condition3) {
}
//do something
}
It is possible to find out which of the conditions was true by querying each of them using another if, effectively rendering the first if useless.
A simple method.
if(condition1 || condition2 || condition3)
{
if(condition1){
//do something
}
if(condition2){
//do something
}
if(condition3){
//do something
}
}
Or if you know that only one of the conditions is going to be true, consider using a switch.
Before you call the if statement, you can call:
System.out.println(condition1);
System.out.println(condition2);
System.out.println(condition3);
to find out which of the conditions was true.
If you would like to make the program behave differently according to the condition you will need to put that code in a separate if statement.
No. However you can achieve by:
i. Using seperate if else within the 3 or conditions
or
ii. break the three or conditions in separate pairs to find out matching value
You have the short circuit operators. || and &&.
So say for instance you have the condition,
if( x && y || z)
If x && y doesnt evaluate to true, then y and z are never compared. However if X and Y are true, then it will test y or z. In this case your true value comes from the fact that x and y is true, and y or z is true.
Related
I have two conditions, ShouldCheckForErrors and HasErrors
My code is
if(ShouldCheckForErrors && HasErrors)
{
//Do nothing
}
else
{
PassTest()
}
I feel like this is a very longwinded check. Isn't there a way that I can do a single check without having to use else?
For example:
if(!ShouldCheckForErrors && !HasErrors)
{
PassTest()
}
does not work, because that would fail to call PassTest() when ShouldCheckforErrors is true, but HasErrors is false. (And vice versa)
I just feel like I am forgetting something with my Logical Operators.
You're looking for De Morgan's Law:
if (!ShouldCheckForErrors || !HasErrors)
To put it differently:
You should pass either if there are no errors, or if we aren't checking errors.
Use not operator ! after you get result of both conditions
if(!(ShouldCheckForErrors && HasErrors))
{
PassTest();
}
Your logic is a bit off
!ShouldCheckForErrors && !HasErrors
is not the same as
!(ShouldCheckForErrors && HasErrors)
which is what I believe you want
Simpler case -
if(theOnlyCheck) {
}
else {
do();
}
You seem to be savvy enough to shorten this check -
if(!theOnlyCheck) {
do();
}
But you simply mess up your order of operations.
Substitute (check1 && check2) for theOnlyCheck. Don't forget parentheses:
if(!(check1 && check2)) {
do();
}
Now if you don't like dealing with these parentheses you can follow De Morgan's Law: !(a && b) is the same as !a || !b. Think it through yourself to see -
if(!check1 || !check2) {
do();
}
I have 3 booleans on my code (C#) and an int32 property that depends on what booleans are true and false.
Whats the best way to accomplish this in another way than if statements like:
if(a && b && !c)
d = 1;
if(a && !b && !c)
d = 2;
//etc.. ect...
EDIT: The 3 booleans must have every combination possible to set the int32 value.
EDIT 2: The value of "d" can be the same for two different boolean comparations.
It is better to capture the intent of the operation instead of explicitly check the boolean values.
For example:
public void Check()
{
if (HasOrdered())
{
// do logic
}
}
private bool HasOrdered()
{
return a && !b && !c;
}
private bool HasBooked()
{
return a && b && !c;
}
You could use a Karnaugh map to reduce your equations and have fewer ifs.
https://en.wikipedia.org/wiki/Karnaugh_map
I think what your doing now is perfectly fine and any other solutions would be down to preference.
My preference, where it applies would be to separate the checks out if possible.
if (!a)
return;
if (!b)
return;
if (!c)
return;
This would be useful in the event that you need to check certain prereqs before issuing a function, like if the user has logged in, if a parameter exists and is in the right context, along with other items.
Like i said this might not apply but i just wanted to voice my opinion
You could do the lookup table hint given by #Adriano, assuming you have lookup_table filled with values for index [0..8):
var index = new [] { a,b,c }.Aggregate(0, (a,i) => return 2*a + (i?1:0));
int d = lookup_table[index];
Edit The EDIT of the question made this irrelevant: What does d mean?
If it's the count of false values (possible from the sample code), make it
int d = new [] { a,b,c }.Count(b => !b);
I don't see anything wrong with how you're doing it, but if the output is the same for multiple conditions you may be able to simplify if by creating a truth table and simplifying the conditions.
For example, if d should be 0 anytime a is false you could simplify to:
if(a)
if(b && !c)
d = 1;
if(!b && !c)
d = 2;
...
else
d = 0;
Or if there is some mathematical pattern (e.g. a, b, and c represent the three digits of a binary number) then you could do bit arithmetic.
If, however, you have 8 distinct outcomes (one for each combination of a, b, and c) then your method is fine.
I have the following block of code:
if (x > 5)
{
if (!DateTime.TryParse(y, out z))
break;
if (w.CompareTo(z) == -1)
break;
}
Where x is an integer, y is a string, z and w are DateTime variables.
The reason for the break; is that whole block resides within a loop.
Is there any way this could be simplified to make it easier to read?
You don't need multilpe if blocks to execute the code because you are only doing one of two things, executing the loop or not executing the loop (one if and one else). As shown here you can use a single boolean expression to represent whether or not you should skip that loop iteration or not.
(x > 5) && (!DateTime.TryParse(y, out z) || w.CompareTo(z) == -1)
Having said that, including a complex condition like this inside of a loop can hamper readability. Personally, I would simply extract this condition out into a method so that the loop looked something like this:
while(!done) // or whatever the while loop condition is
{
if(itemIsValid(x, y, w, out z))
{
//the rest of your loop
}
}
//it may make sense for x, y, w, and possibly z to be wrapped in an object, or that already may be the case. Consider modifying as appropriate.
//if any of the variables are instance fields they could also be omitted as parameters
//also don't add z as an out parameter if it's not used outside of this function; I included it because I wasn't sure if it was needed elsewhere
private bool itemIsValid(int x, string y, DateTime w, out DateTime z)
{
return (x > 5)
&& (!DateTime.TryParse(y, out z) || w.CompareTo(z) == -1)
}
This has several advantages. First, it is a way of self-documenting the code without even needing comments. When looking at the loop you can read it as, "while I'm not done, and if the item is valid, do all of this stuff". If you are interested in how validity is defined you look at the method, if not you skip it. You could also rename the method to something more specific, such as "isReservationSlotFree" or whatever this is actually representing.
If your validation logic is complex (this is somewhat complex) it allows you to add comments and explanation without cluttering the more complex loop.
if (x > 5)
{
if(!DateTime.TryParse(y,out z) || w.CompareTo(z) == -1)
break;
}
Since the two conditionals have the same result, they can be combined into one.
if ((x > 5) && (!DateTime.TryParse(y, out z) || w.CompareTo(z) == -1))
break;
'Simplified' does not mean easier to read.
You can make your code easier to read (and more secured in regards of various coding rules) by:
1) always using brackets for if statements and alikes
2) avoid using '!' ( '== false' is much more explicit)
3) use variable names that explicit what those variables are.
4) avoid multiple break statements. Instead, use a flag that is evaluated in the while's condition.
5) if your code is still hard to read: use comments !
More important: use descriptive variable names for w, x, y, z (hopefully these names were just for your example):
You can also use the less than or greater than operators instead of CompareTo.
if (x > 5)
{
bool isValidDate = DateTime.TryParse(y, out z);
if (!isValidDate || z > w)
{
// comment like: stop processing if the current date
// is after the reference date, or if there was a parsing error
break;
}
}
Here is one more version.
var Break = x > 5 ? ((!DateTime.TryParse(y, out z) || w.CompareTo(z) == -1) ? true : false) : false;
Short but hampers the readability.
if ( x > 5 ){
if (!DateTime.TryParse(y, out z) || w.CompareTo(z) == -1) break;
}
Should be a simple question for the C# experts here.
I basically want to check if one value or another is TRUE, a wild stab at the code is below:
if ((Boolean.Parse(staff.getValue("Male")) | Boolean.Parse(staff.getValue("Female")))
{
// is true
}
Is this correct?
Thanks
If EXACTLY ONE should be true then it is:
var male = bool.Parse(staff.getValue("Male"));
var female = bool.Parse(staff.getValue("Female"));
if (male ^ female)
{
//is true
}
Sounds like you're looking for the logical OR.
if(condition1 || condition2)
{
}
Use the || (double pipe), logical OR.
bool isMale = Boolean.Parse(staff.getValue("Male");
bool isFemale = Boolean.Parse(staff.getValue("Female");
if (isMale || isFemale) // note double pipe ||
{
// do something if true
}
In C# statement expressions are evaluated from left to right. In an OR operation, the second expression will not be evaluated if the first one equals true.
The conditional OR operator || is what you need
if ((Boolean.Parse(staff.getValue("Male")) || Boolean.Parse(staff.getValue("Female")))
{
//is true
}
If the first condition is TRUE, then the second condition isn't checked since the outcome is obviously going to return TRUE.
Note that TryParse works more fast and more safe then just Parse because doesn't throw an exception in case of error. TryParse returns bool that indicates was parse successful or was not.
So both parsing methods should return true and only after that - do the main check
bool male, female;
if ((Boolean.TryParse(staff.getValue("Male"), out male) &&
Boolean.TryParse(staff.getValue("Female"), out female)) &&
(male || female)) // or ^
{
// do stuff
}
or
bool male, female;
if (Boolean.TryParse(staff.getValue("Male"), out male) &&
Boolean.TryParse(staff.getValue("Female"), out female))
{
if(male) { }
else if (female) { } // or just else
}
else
{
// staff contains wrong data. Probably "yeap" instead of "true"
}
To indicate whether a gender is specified with a value of "true" rather than "false",
bool genderIsSpecified = staff.getValue("Male") | staff.getValue("Female");
.. will only determine whether it's one of those values, not which of those values the object staff is.
So, just in case this question is literal and not an abstract example, ...
Male or Female .. everyone is one or the other. Perhaps in your question you meant to ask which of the two is the case? In that case,
bool defaultGenderIfNoGenderDocumented = true; // male
bool MaleIfTrue_FemaleIfFalse = !string.IsNullOrEmpty(staff.getValue("Male"))
? bool.Parse(staff.getValue("Male"))
: string.IsNullOrEmpty(staff.getValue("Female"))
? bool.Parse(staff.getValue("Female"))
? false
: defaultGenderIfNoGenderDocumented
: defaultGenderIfNoGenderDocumented;
Or simply,
// assume value is properly populated, ignore "Female" value
bool isMale = bool.Parse(staff.getValue("Male"));
This is a similar scenario but I am checking for three or more bool values.
Thread th = new Thread(() =>
{
while (true)
{
bool allReadComplete = true;
foreach (IDataProvider provider in lstDataProviders)
{
provider.StartReading();
if (provider.FinishedReading)
allReadComplete = allReadComplete && provider.FinishedReading;
else
allReadComplete = provider.FinishedReading;
}
// to induce some context switching
Thread.Sleep(0);
if (allReadComplete)
break;
}
Console.WriteLine("Thread Exiting");
});
th.IsBackground = true;
th.Start();
A little exception checking is needed anyway. The Boolean.Parse() method gets a string as argument and returns either true or false only if the argument, once stripped out of whitespace, is equal to "True" or "False" (note capitalization). In ANY other case the function returns an exception.
Supposing that the possible values of staff.getValue("Male") and staff.getValue("Female") are exactly those two, then the simple disjunction (||) is sufficient. If any other return value is possible, including null and the empty string, then you have to check for exceptions
bool isMale;
try {
isMale = Boolean.Parse(staff.getValue("Male"));
} catch(Exception e) {
isMale = Boolean.False;
}
try {
isFemale = Boolean.Parse(staff.getValue("Female"));
} catch(Exception e) {
isFemale = Boolean.False;
}
if (isMale || isFemale) // note double pipe ||
{
// do something if true
}
or compare manually
bool isMale = Boolean.TrueValue == staff.getValue("Male");
bool isFemale = Boolean.TrueValue == staff.getValue("Female");
if (isMale || isFemale) // note double pipe ||
{
// do something if true
}
I came across the following expression in someone else's code. I think it's terrible code for a number of reasons (not least because it fails to take into account bool.TrueString and bool.FalseString), but am curious as to how the compiler will evaluate it.
private bool GetBoolValue(string value)
{
return value != null ? value.ToUpper() == "ON" ? true : false : false;
}
Edit
Incidentally, aren't the expressions evaluated from the inside-outwards? In this case, what's the point of checking for value != null after the call to value.ToUpper() which will throw a null reference exception?
I think the following is a correct (deliberately) verbose version (I'd never leave it like this :D ):
if (value != null)
{
if (value.ToUpper() == "ON")
{
return true;
}
else // this else is actually pointless
{
return false;
}
}
else
{
return false;
}
Which can be shortened to:
return value != null && value.ToUpper == "ON";
Is this a correct re-writing of the expression?
It looks like the method is indended to handle a value that comes from a checkbox HTML element. If no value is specified for the checkbox, it uses the value "on" by default. If the checkbox is not checked there is no value at all from it in the form data, so reading the key from Request.Form gives a null reference.
In this context the method is correct, althought it's quite horrible due to the use of the if-condition-then-true-else-false anti-pattern. Also it should have been given a name that is more fitting for it's specific use, like GetCheckboxValue.
Your rewrite of the method is correct and sound. As the value is not culture dependant, converting the value to uppercase should not use the current culture. So a rewrite that is even slightly better than the one that you proposed would be:
return value != null && value.ToUpperInvariant == "ON";
(The culture independent methods are also a bit faster than the ones using a specific culture, so there is no reason not to use them.)
Incidentally, aren't the expressions
evaluated from the inside-outwards?
If it was method calls so that all expressions were actually evaluated, they would, as the inner call has to be made to evaluate the parameters for the outer call.
However, the second and third operands of the conditional expression is only evaluated if they are used, so the expressions are evaluated from the outside and inwards. The outermost condition is evaluated first to decide which of the operands it will evaluate.
You are correct, both in your rewriting and in your assertion that this attempt at conciseness is bad because it leads to confusion.
well the first one is a double-nested ternary operator
return (value != null) ? [[[value.ToUpper() == "ON" ? true : false]]] : false;
The bit in [[[ ]]] is the first result of the ternary expression which gets evaluated
when the first condition is true so you're reading/assertion of it is correct
but its ugly as hell and very unreadable/unmaintainable in its current state.
I'd definitely change it to your last suggestion
SideNote:
People who do
if(X == true)
return true;
else
return false;
instead of
return X;
should be taken out and shot ;-)
Are you looking for speed or readability and organization? Speed of execution, your shortened example is probably the best way to go.
For a few extra milliseconds, you could re-write this utility method as an extension method like so:
public static bool ToBoolean(this string value)
{
// Exit now if no value is set
if (string.IsNullOrEmpty(value)) return false;
switch (value.ToUpperInvariant())
{
case "ON":
case "TRUE":
return true;
}
return false;
}
... and then you would use it as follows:
public static void TestMethod()
{
bool s = "Test".ToBoolean();
}
EDIT:
Actually, I'm wrong... a quick performance test shows that the extension method is FASTER than the inline method. The source of my test is below, as well as the output on my PC.
[Test]
public void Perf()
{
var testValues = new string[] {"true", "On", "test", "FaLsE", "Bogus", ""};
var rdm = new Random();
int RunCount = 100000;
bool b;
string s;
Stopwatch sw = Stopwatch.StartNew();
for (var i=0; i<RunCount; i++)
{
s = testValues[rdm.Next(0, testValues.Length - 1)];
b = s.ToBoolean();
}
Console.Out.WriteLine("Method 1: {0}ms", sw.ElapsedMilliseconds);
sw = Stopwatch.StartNew();
for (var i = 0; i < RunCount; i++)
{
s = testValues[rdm.Next(0, testValues.Length - 1)];
b = s != null ? s.ToUpperInvariant() == "ON" ? true : s.ToUpperInvariant() == "TRUE" ? true : false : false;
}
Console.Out.WriteLine("Method 2: {0}ms", sw.ElapsedMilliseconds);
}
Output:
Method 1: 21ms
Method 2: 30ms
I read the original expression the same way you do. So I think your shortened expression is correct. If value is null it will never get to the second conditional, so it looks safe to me.
I also hate the constructs like:
if (value.ToUpper() == "ON")
{
return true;
}
else // this else is actually pointless
{
return false;
}
as you noticed it is a long and convoluted (not to say stupid) way of writing:
return value.ToUpper() == "ON";
Your proposition is nice, short and correct.
Another alternative:
return string.Equals( value, "ON", StringComparison.OrdinalIgnoreCase );