IF function with && and || at the same time - c#

I want to do IF under serveral condition AND && and OR || on it
i have two range of number
Top1 - Bottom1 and
Top2 - Bottom2
and only executed when Currentnumber is within these two range
am i doing it okay ?
if (OnlyAbove == True
&& (Top1 > Currentnumber || Top2 > Currentnumber)
&& (Bottom1 < Currentnumber || Bottom2 < Currentnumber)
)
{
Statement
}

I'm going to go out on a limb and say: no, you're not doing right on this one - mostly because what your code is currently doing doesn't make sense.
One thing that helps out with stuff like this is to phrase it in common english - so you go from:
if (OnlyAbove == True
&& (Top1 > Currentnumber || Top2 > Currentnumber)
&& (Bottom1 < Currentnumber || Bottom2 < Currentnumber)
)
{
Statement
}
... to ...
if OnlyAbove
AND (CurrentNumber above at least one of the two Tops)
AND (CurrentNumber below at least one of the bottoms)
After all, the stuff between those inner parenthesis is saying "Top1 > current OR Top2 > current" - which really isn't what you're looking for.
Something that'll help out - not only writing code like this, but reading it down the line, is to go a bit overboard with variables. Variables are awesome at helping you document logic, since you can name them very descriptively.
So imagine code that looks like this:
bool betweenRange1 = (Currentnumber > Bottom1) && (Currentnumber < Top1);
bool betweenRange2 = (Currentnumber > Bottom2) && (Currentnumber < Top2);
if (OnlyAbove && betweenRange1 && betweenRange2)
{
Statement
}
... that IF statement starts to look a lot more readable - it's obvious at a glance at what it's getting at. If you're having trouble parsing IF statements, it's not a bad habit to get into. Maybe a bit overkill... but overkill's a lot better than having code you're not sure of what it's doing :-)

Related

Expression brain fade

I'm having brain fade trying to write a single logical expression that suits the question's comment
// **Don't do xyz between 10.00pm and 7:30am**
//
if(hour > 22 || (hour < 7 && minutes < 30)
output("too early or too late");
Without coming up with something god awful like:
if (hour > 20)
"Too late";
if (hour < 7)
"Too early"
else
if (hour == 7 && minute < 30)
"Too early"
Please put me out of my misery.
|| is your friend here. If you have multiple conditions and if any of them are true you want to do something then instead of using
if (condition1)
do_something();
if (condition2)
do_something();
if (condition3)
do_something();
You can use
if (condition1 || condition2 || condition3)
do_something();
So to relate that to what you have your single if statement would be
if(hour > 21 || hour < 7 || (hour == 7 && minute < 30))
output("too early or too late");

How to lower IL nesting depth?

I am giving NDepend a try for 2 weeks now. I still couldn't really figure it out on how to lower ILNestingDepth. I have few methods left marked as "Methods too complex - critical". And as a fix method they suggest to seperate method into smaller methods. But I couldn't fix it that way. Let me show you a method:
First Version: ILNesting Depth of Appropriate = 7
public bool Appropriate ( CompanyQuota available, CompanyQuota used )
{
/// - larger than available or
/// - less than already used area
return !( DiskQuota > available.DiskQuota || DiskQuota < used.DiskUsage ||
UploadQuota > available.UploadQuota || UploadQuota < used.UploadUsage ||
DownloadQuota > available.DownloadQuota || DownloadQuota < used.DownloadUsage ||
PersonnelQuota > available.PersonnelQuota || PersonnelQuota < used.PersonnelUsage );
}
Second Version: ILNesting Depth of Appropriate = 7
public bool Appropriate ( CompanyQuota available, CompanyQuota used )
{
/// - larger than available or
/// - less than already used area
return AvailableFromTop(available) || AvailableFromBottom(used);
}
bool AvailableFromTop ( CompanyQuota available )
{
return !( DiskQuota > available.DiskQuota ||
UploadQuota > available.UploadQuota ||
DownloadQuota > available.DownloadQuota ||
PersonnelQuota > available.PersonnelQuota );
}
bool AvailableFromBottom ( CompanyQuota used )
{
return !( DiskQuota < used.DiskUsage ||
UploadQuota < used.UploadUsage ||
DownloadQuota < used.DownloadUsage ||
PersonnelQuota < used.PersonnelUsage );
}
How does it really work?
What should I really do?
As #Patrick from NDepend team says on the comments this was a false positive report. Hence this question does not need an answer.
For the sake of the community I am keeping this question here with the answer containing only the comment of Patrick, for the "too-lazy-to-read-comments" people.

C#: Choosing operator depending on boolean value (in one line)

I'm trying to get away with a slick one liner as I feel it is probably possible.
I'll put my code below and then try to explain a little more what I'm trying to achieve.
for (int p = 0; p < 2; p++)
{
foreach (string player in players[p])
{
if (PlayerSkills[player].streak_count *>* 0) //This line
PlayerSkills[player].streak_count++;
else
PlayerSkills[player].streak_count = 0;
}
}
*(p==0 ? >:<) the comparison operator is chosen depending on p.
Of course what I've written is rubbish. But basically I want to use >0 when p==0, and <0 when p>>0. Is there a nice way to achieve this?
Well, you should use what is most readable, even if it is not as consice. That said...
// Invert the count for all but the first player and check for a positive number
if (PlayerSkills[player].streak_count * (p==0 ? 1 : -1) > 0)
I don't know about slick, but the following and/or combination is one line:
if ((p == 0 && PlayerSkills[player].streak_count > 0)
|| PlayerSkills[player].streak_count < 0)
...
This will only ever do the array index once (due to the p==0 condition occurring first) and so is equivalent to the "ternary" you wrote (albeit a bit more verbose).
p > 0 ? whenGreaterThanZero : whenZeroOrLess ;
E.g.
int p = 1; bool test = p > 0 ? true : false ;
Lets test = True

Check if intersecting within a 1 "block" radius

I have two positions on a 3D system, say [15, 32, 42] and [16, 32, 42]
Is there a easy way to check if they are within a 1 block radius from each other?
This is what I have, but is there a better way of doing it:
if (pos[0] == pos1[0] / 32 || pos[0] == pos1[0] + 1 || pos[0] == pos1[0] - 1)
{
if (pos[1] == pos1[1] || pos[1] == pos1[1] - 1 || pos[1] == pos1[1] + 1)
{
if (pos[2] == pos1[2] || pos[2] == pos1[2] + 1 || pos[2] == pos1[2] - 1)
{
Thanks,
David
You can use Math.abs(pos[0]-pos1[0]) <= 1 to check if two coordinates in the same plane are at most 1 apart.
So all in all, your code could look like this:
if( Math.abs(pos[0]-pos1[0]) <= 1
&& Math.abs(pos[1]-pos1[1]) <= 1
&& Math.abs(pos[2]-pos1[2]) <= 1 )
{
Within a 1 block radius
}
Note that I do not understand why you divided your first equation by 32. I did not include that in this answer.
Note also that this solution makes things a little more readable, but that yours is correct too.
I haven't done this in c# but in Java I use JTS. http://geoapi.codeplex.com/ seems to provice the same functionality in c#. Then you will represent your points as Point objects and have all sorts of useful geospatial functions to use.
But for this case, are you looking for the "as the crow flies" distance, which is just pythagoras, or the "walking distance", which would involve finding the shortest valid route in a directed graph of footpaths?
Julian

"<= is an invalid expression term" and ") expected"

I am messing around with C# and am making a prototype GUI (with no game attached, just messing around with buttons and button colors). I'm running into an error:
private void temperValue_Load(object sender, EventArgs e)
{
int temperInt = 23;
temperInt = Convert.ToInt32(temperValue.Text);
if (temperInt >= 70)
{
temperButton.BackColor = System.Drawing.Color.Red;
}
else if (temperInt >= 40 & <= 69)
{
temperButton.BackColor = System.Drawing.Color.DarkOrange;
}
}
On the "else if" line, I have an error from both the "<=" and the "69)". The "<=" error is "Invalid expression term '<='", and the four errors for the "69)" is ") expected", "Invalid expression term ')'", and two "; expected" errors.
There are no variables outside of this snippet of code that are affecting this code. Every variable called is defined inside the snippet.
(For anyone curious, "temper" stands for "Temperature")
You cannot take shortcuts in your boolean conditions like that.
else if (temperInt >= 40 & <= 69)
Must instead be written as:
else if (temperInt >= 40 && temperInt <= 69)
Note that when making boolean comparisons, you usually want to use the double ampersand &&. This causes short-circuiting (only evaluate both sides if the left side succeeds) which is usually what is wanted. And as I said, you need to include the temperInt identifier both times -- you can't say "where some variable is greater than one value and less than another" like in a SQL BETWEEN clause.
Update: Fixed answer per Eric's suggestion.
if (temperInt >= 40 & <= 69) ...
is not valid C#. Computer languages are a little more restrictive than natural languages. You should use:
if (temperInt >= 40 && temperInt <= 69) ...
(you'll notice I'm also using the logical && operator rather than the bitwise & operator - the former is for truth values, the latter usually for bit manipulation, see this answer for details).
There's another alternative, the use of extension methods:
bool IsBetween (this int me, int lower, int upper) {
return (me >= lower) && (me <= upper);
}
if (temperInt.IsBetween (40, 69)) ...
which is closer to natural language, but that's probably overkill for this case.
you probablly meant temperInt >= 40 && temperInt <= 69
else if (temperInt >= 40 & <= 69)
Should be:
else if (temperInt >= 40 && temperInt <= 69)
You need to include the variable in both parts of the statement, and & is a bitwise AND whereas && is a logical AND which is what you want in this case.
There are a few errors in the given code.
else if (temperInt >= 40 & <= 69)
{
temperButton.BackColor = System.Drawing.Color.DarkOrange;
}
This should actually read
else if (temperInt >= 40 && temperInt <= 69)
{
temperButton.BackColor = System.Drawing.Color.DarkOrange;
}
The && is the logical AND operator in C# and not the '&'. Also the LHS part need to be used in all equality comparisons and not chained like your code sample.

Categories