I have a report that uses parameters to hide or show data on a chart at runtime. I have the following code to read the parameter and use it to control the visibility of the axes.
((SplineSeriesView)xrChart1.Series[0].View).AxisY.Visible = Convert.ToBoolean(this.Parameters[0].Value);
((SplineSeriesView)xrChart1.Series[1].View).AxisY.Visible = Convert.ToBoolean(this.Parameters[1].Value);
((SplineSeriesView)xrChart1.Series[2].View).AxisY.Visible = Convert.ToBoolean(this.Parameters[2].Value);
((SplineSeriesView)xrChart1.Series[3].View).AxisY.Visible = Convert.ToBoolean(this.Parameters[3].Value);
((SplineSeriesView)xrChart1.Series[4].View).AxisY.Visible = Convert.ToBoolean(this.Parameters[4].Value);
((SplineSeriesView)xrChart1.Series[5].View).AxisY.Visible = Convert.ToBoolean(this.Parameters[5].Value);
Because series 0 and series 1 are both tied to the same axis, I am using an or operator. The problem that I am having is that the axis will not hide when they are both false. This is the code that I am using:
bool zero = Convert.ToBoolean(this.Parameters[0].Value);
bool one = Convert.ToBoolean(this.Parameters[1].Value);
if ((zero = true)||(one = true))
{
((SplineSeriesView)xrChart1.Series[0].View).AxisY.Visible = true;
}
else if ((zero = false) && (one = false))
{
((SplineSeriesView)xrChart1.Series[0].View).AxisY.Visible = false;
}
How can I get the axis to hide? Thank you in advance for your help.
It's important to remember the difference between equality comparison == and the settor operator =. In your if statement, you're using the settor, and want to be using the comparison.
If you use the proper operator, your code could look like this, and that should solve your issue:
if ((zero == true)||(one == true))
{
((SplineSeriesView)xrChart1.Series[0].View).AxisY.Visible = true;
}
else if ((zero == false) && (one == false))
{
((SplineSeriesView)xrChart1.Series[0].View).AxisY.Visible = false;
}
The reason you were having problems is that you were using the settor, which was automatically setting zero and one to true. Thus, the program was evaluating your if statement as: "if (true or true)", which is always true. This is why setting the values to false wasn't working.
Incidentally, there are a few things you could've done to avoid this mistake. First, your compiler should have warned you that you weren't using an equality operator. Second, you could get in the habit of putting constants first: if (false = zero) would generate a compile-time error. (Personally, I really don't like that coding style, it doesn't read cleanly to me, but your mileage may vary.)
I'd rewrite your statements to be a lot cleaner, but functionally equivalent:
if (zero || one)
{
((SplineSeriesView)xrChart1.Series[0].View).AxisY.Visible = true;
}
else
{
((SplineSeriesView)xrChart1.Series[0].View).AxisY.Visible = false;
}
When you're putting boolean variables in to an if statement, there's no good reason to compare them to boolean constants. Your second if isn't necessary at all, since it's the only case that can happen if the first one doesn't. (i.e. "if !(zero || one)" === "!zero && !one" - it's called DeMorgan's Rule.)
In fact, your whole if statement can be condensed down to one clear line:
((SplineSeriesView)xrChart1.Series[0].View).AxisY.Visible = zero || one;
I think that your problem was in using '=' instead of '=='. The expression zero = true sets zero to true and this true value is used as expression value. So, after first condition checking 'zero' always becomes true and 'else' branch never executes because 'zero' is no longer false.
In fact, expression zero == true is equal to just zero, so you can simplify your condition:
bool zero = Convert.ToBoolean(this.Parameters[0].Value);
bool one = Convert.ToBoolean(this.Parameters[1].Value);
if (zero || one) // true if 'zero' or 'one' is true
{
((SplineSeriesView)xrChart1.Series[0].View).AxisY.Visible = true;
}
else // goes here if both 'zero' and 'one' is false
{
((SplineSeriesView)xrChart1.Series[0].View).AxisY.Visible = false;
}
Or even
bool zero = Convert.ToBoolean(this.Parameters[0].Value);
bool one = Convert.ToBoolean(this.Parameters[1].Value);
bool axisVisible = zero || one;
((SplineSeriesView)xrChart1.Series[0].View).AxisY.Visible = axisVisible;
Related
double number;
bool isParsed = false;
while(!isParsed)
{
Console.WriteLine("Enter the value");
isParsed = double.TryParse(Console.ReadLine(), out number);
if(isParsed)
{
break;
}
Console.WriteLine("Invalid value");
}
A friend and I were studying this code block. I found this part to understand:
bool isParsed = false;
while(!isParsed)
I thought that if isParsed = false, and the while loop will check the negation (!isParsed) to see if it should run, wouldn't this be the logic:
while(!isParsed) => while(NOT(false)) => while (true)?
Therefore, the while loop would never run. But it does run. Later I understood that a check was happening:
while (!isParsed) => while((!isParsed) == true),
but he says that not exactly what is happening.
Can someone explain what is happening here?
You're saying it correctly: while (true). That true boolean condition denotes that the next (and first) iteration will run.
!false == true
Take a look at the MSDN documentation stating the behavior of the while loop: https://msdn.microsoft.com/en-us/library/2aeyhxcd.aspx
When using a boolean in an expression you are checking for a value of true. When adding the logical NOT operator, you are now looking for a value of false.
while (false)
bool isParsed = false;
while(!isParsed)
Loop should run, at least once; Which is correct behavior, since your condition is evaluating to true.
here is a function prints repeating int in a array.
in c#:
int [] ReturnDups(int[] a)
{
int repeats = 0;
Dictionary<int, bool> hash = new Dictionary<int>();
for(int i = 0; i < a.Length i++)
{
bool repeatSeen;
if (hash.TryGetValue(a[i], out repeatSeen))
{
if (!repeatSeen)
{
hash[a[i]] = true;
repeats ++;
}
}
else
{
hash[a[i]] = false;
}
}
int[] result = new int[repeats];
int current = 0;
if (repeats > 0)
{
foreach(KeyValuePair<int,bool> p in hash)
{
if(p.Value)
{
result[current++] = p.Key;
}
}
}
return result;
}
now converted to JAVA by Tangible software's tool.
in java:
private int[] ReturnDups(int[] a)
{
int repeats = 0;
java.util.HashMap<Integer, Boolean> hash = new java.util.HashMap<Integer>();
for (int i = 0; i < a.length i++)
{
boolean repeatSeen = false;
if (hash.containsKey(a[i]) ? (repeatSeen = hash.get(a[i])) == repeatSeen : false)
{
if (!repeatSeen)
{
hash.put(a[i], true);
repeats++;
}
}
else
{
hash.put(a[i], false);
}
}
int[] result = new int[repeats];
int current = 0;
if (repeats > 0)
{
for (java.util.Map.Entry<Integer,Boolean> p : hash.entrySet())
{
if (p.getValue())
{
result[current++] = p.getKey();
}
}
}
return result;
}
but findbug find this line of code as bugs. and it looks very odd to me too.
if (hash.containsKey(a[i]) ? (repeatSeen = hash.get(a[i])) == repeatSeen : false)
can someone pls explain to me what this line does and how do i write it in java properly?
thanks
You have overcomplicated the code for TryGetValue - this simple translation should work:
if ( hash.containsKey(a[i]) ) {
if (!hash.get(a[i])) {
hash.put(a[i], true);
}
} else {
hash.put(a[i], false);
}
C# has a way to get the value and a flag that tells you if the value has been found in a single call; Java does not have a similar API, because it lacks an ability to pass variables by reference.
Do not directly convert C# implementation. assign repeatSeen value only if the id is there.
if (hash.containsKey(a[i]))
{
repeatSeen = hash.get(a[i]).equals(repeatSeen)
if (!repeatSeen)
{
hash.put(a[i], true);
repeats++;
}
}
To answer the actual question that was asked:
if (hash.containsKey(a[i]) ? (repeatSeen = hash.get(a[i])) == repeatSeen : false)
is indeed syntactically wrong. I haven't looked at the rest of the code, but having written parsers/code-generators in my time I'm guessing it was supposed to be
if (hash.containsKey(a[i]) ? (repeatSeen = hash.get(a[i])) == repeatSeen) : false)
It's gratuitously ugly -- which often happens with code generators, especially ones without an optimizing pass -- but it's syntactically correct. Let's see if it actually does have a well-defined meaning.
CAVEAT: I haven't crosschecked this by running it -- if someone spots an error, please tell me!
First off, x?y:z is indeed a ternary operator, which Java inherited from C via C++. It's an if-then-else expression -- if x is true it has the value y, whereas if x is false it has the value z. So this one-liner means the same thing as:
boolean implied;
if (hash.containsKey(a[i]) then
implied = (repeatSeen = hash.get(a[i])) == repeatSeen);
else
implied = false;
if(implied)
... and so on.
Now, the remaining bit of ugliness is the second half of that and-expression. I don't know if you're familiar with the use of = (assignment) as an expression operator; its value as an operator is the same value being assigned to the variable. That's mostly intended to let you do things like a=b=0;, but it can also be used to set variables "in passing" in the middle of an expression. Hardcore C hackers do some very clever, and ugly, things with it (he says, being one)... and here's it's being used to get the value from the hashtable, assign it to repeatSeen, and then -- via the == -- test that same value against repeatSeen.
Now the question is, what order are the two arguments of == evaluated in? If the left side is evaluated first, the == must always be true because the assignment will occur before the right-hand side retrieves the value. If the right side is evaluated first, we'd be comparing the new value against the previous value, in an very non-obvious way.
Well, in fact, there's another StackOverflow entry which addresses that question:
What are the rules for evaluation order in Java?
According to that, the rule for Java is that the left argument of an operator is always evaluated before the right argument. So the first case applies, the == always returns true.
Rewriting our translation one more time to reflect that, it turns into
boolean implied;
if (hash.containsKey(a[i]) then
{
repeatSeen = hash.get(a[i]));
implied = true;
}
else
implied = false;
if(implied)
Which could be further rewritten as
if (hash.containsKey(a[i]) then
{
repeatSeen = hash.get(a[i]));
// and go on to do whatever else was in the body of the original if statement
"If that's what they meant, why didn't they just write it that way?" ... As I say, I've written code generators, and in many cases the easiest thing to do is just make sure all the fragments you're writing are individually correct for what they're trying to do and not worry about whether they at all resemble what a human would have written do do the same thing. In particular, it's tempting to generate code according to templates which allow for cases you may not actually use, rather than trying to recognize the simpler situation and generate code differently.
I'm guessing that the compiler was drawing in and translating bits of computation as it realized it needed them, and that this created the odd nesting as it started the if, then realized it needed a conditional assignment to repeatSeen, and for whatever reason tried to make that happen in the if's test rather than in its body. Believe me, I've seen worse kluging from code generators.
Which is better of the following?
this.isLoggedIn = (bool)HttpContext.Current.Session["li"] == true;
or
this.isLoggedIn = (bool)HttpContext.Current.Session["li"];
It needs be to true ONLY when the session is true. If the session is set to false will this evaluate to true in #2 as it exists? Or is it evaluating its value?
The second one:
this.isLoggedIn = (bool)HttpContext.Current.Session["li"];
(bool)HttpContext.Current.Session["li"] is already a boolean (so will be either true or false), so no need for the extra comparison and return value of the boolean expression.
Either way, you need to check that the li session variable exists before trying to cast it, or your code will throw (I think a NullReferenceException).
The latter is clearer, IMO. They're functionally equivalent though - in both cases, it will fetch the value of "li" from the session and attempt to cast it to bool, throwing an exception if the value isn't present.
Create a property for the desired value:
public bool IsLoggedIn {
get { return (bool)HttpContext.Current.Session["li"]; }
}
You could even go one extra level, if the session is used a lot in the class:
public bool IsLoggedIn {
get { return (bool)Session["li"]; }
}
private HttpSessionState Session {
get { return HttpContext.Current.Session; }
}
Also, if you ever want to look at the session by itself, use a better key, like "IsLoggedIn", instead of "li".
It might be good to create a special class for these application-wide values:
public static class MyAppSession {
const string IsLoggedInKey = "IsLoggedIn";
public static bool IsLoggedIn {
get {
return Session[IsLoggedInKey] != null && (bool)Session[IsLoggedInKey];
}
internal set { Session[IsLoggedInKey] = value; }
}
// ...
private static HttpSessionState Session {
get { return HttpContext.Current.Session; }
}
}
The first and the second approach is equivalent, but the first one is to verbose for my taste. I like the second one much better.
Just as I like this
bool accepted = true;
if( accepted)
{
..
}
Better than
bool accepted = true;
if( accepted == true)
{
..
}
I feel it clearer that way if the variables are properly named.
Just put the expected value in the place of the expression, and it will become pretty clear:
First example:
Before: this.isLoggedIn = (bool)HttpContext.Current.Session["li"] == true;
After: this.isLoggedIn = true == true;
Second example:
Before: this.isLoggedIn = (bool)HttpContext.Current.Session["li"];
After: this.isLoggedIn = true;
Now, try the same for the false case:
First example:
Before: this.isLoggedIn = (bool)HttpContext.Current.Session["li"] == true;
After: this.isLoggedIn = false == true;
Second example:
Before: this.isLoggedIn = (bool)HttpContext.Current.Session["li"];
After: this.isLoggedIn = false;
As you can see, there will be no difference in the result between the two approaches. It all comes down to questions about coding style and readability, where I would guess that you would find a bias towards the shorter version.
You never need to write code that says:
bool x = (y == true);
Instead just use
bool x = y;
In your specific case you should use:
this.isLoggedIn = HttpContext.Current.Session["li"] != null
&& (bool)HttpContext.Current.Session["li"];
This way you will not get an exception if Session["li"] has not been assigned yet. However you will get an exception if Session["li"] is not castable to bool.
I would use the second option with a variant:
this.isLoggedIn = (bool) (HttpContext.Current.Session["li"] ?? "false");
The ?? is null-coalescing operator - it gives a value of "false" to the expression on its lefthand side, in case it happens to be null.
Both pieces of code are equal, so the better is the second (it's shorter).
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 );