l have problem with my c# winform project.
In my project I have a function that switches the location of buttons to their old location if they are in the same area.
private void myText_MouseUp(object sender, MouseEventArgs e)
{
Point q = new Point(0, 0);
Point q2 = new Point(0, 0);
bool flag = false;
int r = 0;
foreach (Control p in this.Controls)
{
for (int i = 0; i < counter; i++)
{
if (flag)
{
if (p.Location.X == locationx[i] && p.Location.Y == locationy[i])
{
oldx = e.X;
oldy = e.Y;
flag = true;
r = i;
}
}
}
}
foreach (Control p in this.Controls)
{
for (int j = 0; j < counter; j++)
{
if ((locationx[j] == p.Location.X) && (locationy[j] == p.Location.Y))
{
Point arrr = new Point(oldx, oldy);
buttons[j].Location = arrr;
buttons[r].Location = new Point(locationx[j], locationy[j]);
}
}
}
}
The problem with this code is that if they are in the same area, the buttons do not switch their locations. Instead they goes to the last button location.
If someone could help me that will help me alot :)
The if statement always evaluates to true. This means that the final j loop will do this:
// last time round the i loop, i == counter-1
// and q == new Point(locationx[counter-1], locationy[counter-1])
for (int j = 0; j < counter; j++)
{
Point q2 = new Point(locationx[j], locationy[j]);
buttons[i].Location = q2;
buttons[j].Location = q;
}
The net result of this is that every button's Location is set to q, which is
new Point(locationx[counter-1], locationy[counter-1])
Why does the if statement always evaluate to true. Well, first of all let's look at a couple of the or clauses in the if statement:
|| ((q.Y >= q2.Y) && (q.X <= q2.X))
|| ((q.Y >= q2.Y) && (q.X == q2.X))
This is equivalent to
|| ((q.Y >= q2.Y) && (q.X <= q2.X))
The line containing the == test has absolutely no impact on the final result of the condition. In fact all the lines containing == can be similarly treated. This leaves:
|| ((q.Y >= q2.Y) && (q.X <= q2.X))
|| ((q.Y >= q2.Y) && (q.X >= q2.X))
|| ((q.Y <= q2.Y) && (q.X >= q2.X))
|| ((q.Y <= q2.Y) && (q.X <= q2.X))
We can condense
|| ((q.Y >= q2.Y) && (q.X <= q2.X))
|| ((q.Y >= q2.Y) && (q.X >= q2.X))
into
|| ((q.Y >= q2.Y)
and similarly
|| ((q.Y <= q2.Y) && (q.X >= q2.X))
|| ((q.Y <= q2.Y) && (q.X <= q2.X))
is the same as
|| ((q.Y <= q2.Y)
Combine
|| ((q.Y >= q2.Y)
|| ((q.Y <= q2.Y)
and you can see that the if condition always evaluates to true.
Related
This is not the actual code but it's what I want to do.
for loop is must but the nested if else loop inside should be executed according to the value of count_final which can be random between 1 to 3.
Like if the value of count_final is 3, all if...else loop should be considered. but if the value of count_final is 2, then only if...(1st)else if and else part only be executed. And if count_final=1 then only if and else part is executed (not any else-if).
Thought of putting another if...else within every if...else and checking count_final, but what if I'm not getting values of count2 and count3 when count_final=1.
Same, when count_final=2, I'm not getting the value of count3.
Ask in comment if you don't understand my question.
int count_final=Session["abc"];
//count_final=1;
//count_final=2;
//count_final=3;
for(int i=1;i<=10;i++)
{
if ((count1 <= count5) && (count1 <= count6))
{
Label1.Text="Hello1";
}
else if (count2 <= count4 && count2 <= count6)
{
Label2.Text="Hello2";
}
else if (count3 <= count4 && count3 <= count5)
{
Label3.Text="Hello3";
}
else
{
Label1.Text="Hello1";
}
}
Seems you have collection of "conditions" where amount of executed conditions depend on value of finalCount.
var rules = new Func<string>[]
{
() => (count1 <= count5 && count1 <= count6) ? "Hello1" : null,
() => (count2 <= count4 && count2 <= count6) ? "Hello2" : null,
() => (count3 <= count4 && count3 <= count5) ? "Hello3" : null
};
Label1.Text = rules.Take(finalCount)
.Select(rule => rule())
.Where(result => result != null)
.DefaultIfEmpty("Hello1")
.First();
Of course this solution is assuming that finalCount is always 1, 2 or 3.
DefaultIfEmpty is playing role of last else - will be used all conditions fails.
if i understand right.. which is a little unlikely
just add more criteria to your ifs!
if ((count1 <= count5) && (count1 <= count6))
{
if (count_final == 3 || count_final == 2) Label1.Text="Hello1";
}
else if (count2 <= count4 && count2 <= count6)
{
if (count_final == 3) Label2.Text="Hello2";
}
else if (count3 <= count4 && count3 <= count5)
{
if (count_final == 3) Label3.Text="Hello3";
}
else
{
if (count_final == 3 || count_final == 1) Label1.Text="Hello1";
}
Remembering that from what I understood there will be loops in that can achieve nothing, eg, if count_final == 2 and its not less or equal to count5 or count6, nothing will happen, same as for count_final == 1, if it matches any of the first bits the last else wont happen.
I suggest extending the conditions of your else if statements:
int count_final=Session["abc"];
//count_final=1;
//count_final=2;
//count_final=3;
for(int i=1; i<=10; i++)
{
if ((count1 <= count5) && (count1 <= count6))
{
Label1.Text="Hello1";
}
else if (count_final >= 2 && count2 <= count4 && count2 <= count6)
{
Label2.Text="Hello2";
}
else if (count_final >= 3 && count3 <= count4 && count3 <= count5)
{
Label3.Text="Hello3";
}
else
{
Label1.Text="Hello1";
}
}
When count_final == 1 this will not try to evaluate count2, count3 or count4 (which I understand is a requirement) because && will not evaluate its right hand side when there is false on the left.
Is this what you are looking for? To use less if/else statements:
int count_final = Session["abc"]; // random between 1 and 3
for(int i=1; i <= 10; i++)
{
switch(count_final)
{
case 3:
Label1.Text="Hello1";
// no break; so all gets executed
case 2:
Label2.Text="Hello2";
case 1:
Label3.Text="Hello3";
default: Label1.Text="Hello1";
}
}
private void btnHasil_Click(object sender, EventArgs e)
{
int rataipa = Convert.ToInt32(NIPA.Text);
int uipa, uipa1, uipa2, uipa3, uipa4;
if ((rataipa >= 61) && (rataipa <= 69))
{
uipa1 = (70 - rataipa) / 10;
uipa2 = (rataipa - 60) / 12;
}
else if ((rataipa == 60) && (rataipa >= 70) && (rataipa <= 72))
{
uipa2 = (rataipa - 60) / 12;
}
else if ((rataipa >= 76) && (rataipa <= 84))
{
uipa3 = (85 - rataipa) / 13;
uipa4 = (rataipa - 75) / 10;
}
else if ((rataipa >= 72) && (rataipa <= 75) || (rataipa == 85))
{
uipa3 = (85 - rataipa) / 13;
}
else
uipa = 1;
}
i try to build the errors shows in variable uipa and it shows the variable 'uipa' is assigned but its value is never used but i used it after that and now i don't know how to fix. anyone can help ?
You assign uipa at the very end of the code but then you never actually do anything with it.
else uipa = 1;
To remove the warning, you need to do something with uipa or remove the above statement entirely. As far as the compiler is concerned, uipa serves no purpose.
If you do decide to use uipa later in say an if statement, be sure to initialise uipa to some default value too else you will run into a different warning about unitialised variables.
int uipa = 0, ....; // initialise uipa here to a default value
.
.
.
else uipa = 1;
if (uipa ==1) // this will solve the variable is assigned but never used problem
{
// do something
}
int rataipa = Convert.ToInt32(NIPA.Text);
int uipa, uipa1, uipa2, uipa3, uipa4;
if ((rataipa >= 61) && (rataipa <= 69))
{
uipa1 = (70 - rataipa) / 10;
uipa2 = (rataipa - 60) / 12;
}
else if ((rataipa == 60) && (rataipa >= 70) && (rataipa <= 72))
{ uipa2 = (rataipa - 60) / 12; }
else if ((rataipa >= 76) && (rataipa <= 84))
{
uipa3 = (85 - rataipa) / 13;
uipa4 = (rataipa - 75) / 10;
}
else if ((rataipa >= 72) && (rataipa <= 75) || (rataipa == 85))
{ uipa3 = (85 - rataipa) / 13; }
else
{ //add this bracket
uipa = 1;
}
I'm trying to create a 2D char array to hold a grid of chars which will be used as a sort of 'map' for a 2D console game.
I am getting a:
IndexOutOfRange exception
..and cannot see why. I've stepped through the code in debug mode and still cannot see the issue.
It steps through the code fine until it hits X = 25 and Y = 1, the upper right boundary of my grid.
I have _gameWidth and _gameHeight created as follows, outside of main but still inside the class:
static int _gameWidth = 25;
static int _gameHeight = 15;
Following is the code that fails, when trying to generate and populate the grid. It fails at this point:
else if (x == _gameWidth && y == 1)
_grid[x, y] = '╕';
static void GenerateGrid()
{
for (int y = 1; y <= _gameHeight; y++)
{
for (int x = 1; x <= _gameWidth; x++)
{
if (x == 1 && y == 1)
_grid[x, y] = '╒';
else if (x == _gameWidth && y == _gameHeight)
_grid[x, y] = '╛';
else if (x == _gameWidth && y == 1)
_grid[x, y] = '╕';
else if (x == 1 && y == _gameHeight)
_grid[x, y] = '╘';
else if ((x != 1 && y == _gameHeight) || (x != _gameWidth && y == 1))
_grid[x, y] = '═';
else if ((x == 1 && y > 1 && y < _gameHeight) || (x == _gameWidth && y > 1 && y < _gameHeight))
_grid[x, y] = '│';
else
_grid[x, y] = 'x';
}
Console.WriteLine("");
}
}
Change
for (int i = 1; i <= gameHeight; i++)
to
for (int i = 0; i < gameHeight; i++)
and do the same for width.
EDIT:
This is because array indexes start at the number 0 and end with the length of the array minus 1.
This exception means that you have accessed an invalid index. From the way you have written the loop I can tell that you think that indexes go from 1 to the length of the array. Arrays are zero-based, though. Use the standard loop form:
for (int i = 0; i < length; i++)
Your loop starts at one. You can use the Visual Studio for loop template. Just type "for<tab><tab>".
Your program might benefit from the Code Review Stack Exchange site.
I've two lists and I assign one of them this way:
var query = Enumerable.Range(0, 1440).Select((n, index) =>
{
if ((index >= 525 && index <= 544) || (index >= 600 && index <= 749) || (index >= 810 && index <= 1079) || (index >= 1300 && index <= 1439))
return 0;
else if (index >= 1080 && index <= 1299)
return 1;
else if (index >= 545 && index <= 599)
return 3;
else if (index >= 750 && index <= 809)
return 4;
else
return 2;
}).ToList();
My second list is named lst2. I want to assign it "0" or "1" depending on my first list query. So, if query is "1" or "2", lst2's same indices and previous indices that are "0" value, should be "1". If the query list is "3" or "4", lst2's same indices and previous indices that are "1" value, should be "0". In addition, if the query's first indice(s) has "3" or "4" value, then lst2's same indice(s) should be "0". For example;
query = {3,3,3,0,0,0,2,2,0,0,0,0,4,4,4,4,0,0,0,0,1,1,1,0,0,2,2,0,0,4,4}
lst2 = {0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}
How can I do this?
EDIT: If query's any indice has 3 or 4 value, lst2's same indice must have 0 value. If query's any indice has 3 or 4 value AND previous indice has 0 value, lst2's same indices must have 0 value. Likewise; If query's any indice has 1 or 2 value, lst2's same indice must have 1 value. If query's any indice has 1 or 2 value AND previous indice has 0 value, lst2's same indices must have 1 value.
An alternative approach, only filling the tracing 0's when needed. Performance wise it's still best to loop reversed, but I only just saw T_D already did that, so as far as the lookahead -> lookback goes, the below is basically the same, but with other syntax and a different trailing 0 filler.
var arr = new int[query.Count];
int cnt = query.Count - 1, toappendindex = -1;
Func<int,int,int> getval = (ind, val) =>
{
if (val == 3 || val == 4) return 0;
if (val == 2 || val == 1) return 1;
if (ind == cnt) return -1;
return arr[ind + 1];
};
for (int ind = cnt; ind >= 0; ind-- )
{
if ((arr[ind] = getval(ind,query[ind])) == -1)
toappendindex = ind; //only if there are trailing 0's
}
if (toappendindex > 0)
for (; toappendindex < arr.Length; toappendindex++) arr[toappendindex] = arr[toappendindex - 1];
//var lst2 = arr.ToList(); if list is needed instead of array, otherwise arr could be used directly
Try doing this.
List<int> query = Enumerable.Range(0, 1440).Select((n, index) =>
{
if ((index >= 525 && index <= 544) || (index >= 600 && index <= 749) || (index >= 810 && index <= 1079) || (index >= 1300 && index <= 1439))
return 0;
else if (index >= 1080 && index <= 1299)
return 1;
else if (index >= 545 && index <= 599)
return 3;
else if (index >= 750 && index <= 809)
return 4;
else
return 2;
}).ToList();
Console.WriteLine(string.Concat("{", string.Join(",", query.ToArray()), "}"));
List<int> lst2 = Enumerable.Range(0, 1440).Select((n, index) =>
{
if (query[index] == 1 || query[index] == 2)
return 1;
else if (query[index] == 3 || query[index] == 4)
return 0;
else
{
int retval = 1;
//look ahead
for (int i = index; i < query.Count; i++)
{
if (query[i] == 1 || query[i] == 2)
{
break;
}
if (query[i] == 3 || query[i] == 4)
{
retval = 0;
break;
}
}
return retval;
}
}).ToList();
Console.WriteLine(string.Concat("{", string.Join(",", lst2.ToArray()), "}"));
Let me know if this is what you are looking for. You can replace List with var if you like. I just like it strong-typed so that I can easily check the output.
I hope this is what you need:
int n = 1440;
byte[] query = new byte[n];
byte[] lst2 = new byte[n];
byte mode = 0;
bool first = true;
for(int index = n-1; index >= 0; index--)
{
if ((index >= 525 && index <= 544) || (index >= 600 && index <= 749) || (index >= 810 && index <= 1079) || (index >= 1300 && index <= 1439))
query[index] = 0;
else if (index >= 1080 && index <= 1299)
query[index] = 1;
else if (index >= 545 && index <= 599)
query[index] = 3;
else if (index >= 750 && index <= 809)
query[index] = 4;
else
query[index] = 2;
if(query[index] == 3 || query[index] == 4)
{
mode = 0;
lst2[index] = 0;
}
else if(query[index] == 1 || query[index] == 2)
{
if(first)
{
//change ending zeros to 1
for(int j=index+1; j < n; j++)
lst2[j] = 1;
first = false;
}
mode = 1;
lst2[index] = 1;
}
else
{
lst2[index] = mode;
}
}
I'm trying to add the integers 6 from 30, except for 22 and 26, to a List using a for loop. But 22 and 26 are still being added. What did I do wrong?
List<int> lineNumbers = new List<int>();
for (int x = 6; x < 30; x++)
{
if ((x != 22) || (x != 26))
{
lineNumbers.Add(x);
}
}
The two integers are not added if the code is like below:
for (int x = 6; x < 30; x++)
{
if (x == 22 )
{
}
else if (x == 26)
{
}
else
{
lineNumbers.Add(x);
}
}
You need to replace the || with &&:
for (int x = 6; x < 30; x++)
{
if ((x != 22) && (x != 26))
{
lineNumbers.Add(x);
}
}
Or perhaps, to be more clear:
for (int x = 6; x < 30; x++)
{
if ((x == 22) || (x == 26))
continue;
lineNumbers.Add(x);
}
Alternatively, you could perform this as a one-liner using LINQ. This isn't necessarily faster or anything, so if your for loop is clearer to you, then keep it as-is.
lineNumbers.AddRange(Enumerable.Range(6, 24).Except(new[] { 22, 26 }));
Change your conditions. Use && instead of ||
if ((x != 22) && (x != 26))
Use && instead of || because you want to match between both conditions.
if ((x != 22) && (x != 26))
You can also do this using LINQ (not necessarily but I like LINQ :)
var lineNumbers = Enumerable.Range(6, 30).Except(new[] {22, 26}).ToList();
Replace if ((x != 22) || (x != 26)) to if ((x != 22) && (x != 26))
Or you can use continue like below :
for (int x = 6; x < 30; x++)
{
if ((x == 22) || (x == 26))
continue;
else
lineNumbers.Add(x);
}