c# List with Arithmetic Operations - c#

I want realize arithmetic operations with my list, in this case:
Column "width" * Column "height" should re-Write the Column "Partial".
I have tried do a loop but It is not working.
I put a breakPoint at the row:
_Area[i].Partial = _Area[i].width * _Area[i].height;
And the debug never stop them I can think this line is not been readed.
This is my Collection View Model:
public class CollectionVM_Area : BindableBase
{
private Values_Area _Area = new Values_Area();
public Values_Area Area
{
get { return _Area; }
set { SetProperty(ref _Area, value); }
}
public CollectionVM_Area()
{
_Area.Add(new Area()
{
width=10,
height=11,
});
_Area.Add(new Area()
{
width=5,
height=5,
Partial=1,
});
bool NeedPartial = false;
int i = 0;
while (NeedPartial = false && i < _Area.Count)
{
if (_Area[i].Partida == true)
{
NeedPartial = true;
}
else
{
i++;
}
}
if (NeedPartial==true)
{
_Area[i].Partial = _Area[i].width * _Area[i].height;
NeedPartial = false;
}
else
{
NeedPartial = true;
}
}
}
My Project is a UWP but I think is no different in with a windows forms in lists, any help is appreciated.

You have two mistalkes in your code. First your while-loop makes an assignement instead of a comparisson (= towards ==). Thus the first term within your while-condition allways evaluates to false. Secondly your calculation is located outside the loop causing the NeedPartial-value to be set but not never be read which I doubt is what you want.
Write this therefor:
bool NeedPartial = false;
int i = 0;
while (NeedPartial == false && i < _Area.Count) // or even simpler: while (!NeedPartial ...)
{
if (_Area[i].Partida == true) // or simply: if (_Area[i].Partida) { ... }
{
NeedPartial = true;
}
else
{
i++;
}
if (NeedPartial==true) // if (NeedPartial) ...
{
_Area[i].Partial = _Area[i].width * _Area[i].height;
NeedPartial = false;
}
else
{
NeedPartial = true;
}
}

Edit: Answered.
The Correct Loop is:
bool NeedPartial = false;
int i = 0;
while (!NeedPartial && i < _Area.Count)
{
if (_Area[i].Partida)
{
NeedPartial = true;
}
else
{
i++;
}
if (NeedPartial)
{
_Area[i].Partial = _Area[i].width * _Area[i].height;
NeedPartial = false;
i++;
}
else
{
NeedPartial = true;
}
}
Thanks to HimBromBeere for your help.

Related

C# loop edit (I can't code, just trying to make a simple edit)

I need this pre-existing script to loop every forever, I do not know much code and am unable to edit this myself, I'm hoping one of you smart boys can assist in the editing of this script.
This script is C# built for a game called Space Engineers where it takes information from a solar panel to determine time of day/light level and respond by turning on the lights or turning off the lights.
//How to use:
//Setup a timer that triggers it self and this programmable block every 5-10 minutes. Then set the light strength(
//when the solar panel gets less kW's than that, the lights are turned on). Then set measureSolarPanelName to
//the customname of the solar panel that you want to use to measure the light. If you want to use a prefix, set
//usePrefix to true und set a prefix. When you set overwrite to true, this script will stop
//working until you deactivate overwrite(= false), for eg. battles.
//Thank you for using my script :)
//Settings:
int lightStrength = 10;
string measureSolarPanelName = "Solar Panel";
bool overwrite = false;
bool usePrefix = false;
string prefix = "[NL]";
//Code
public void Main(string argument) {
if (getSolarPower() < lightStrength) {
triggerLights(1);
} else {
triggerLights(0);
}
}
int getSolarPower () {
bool watts;
string info = GridTerminalSystem.GetBlockWithName(measureSolarPanelName).DetailedInfo;
var lines = info.Split('\n');
var output = lines[1].Split(':')[1].Trim();
var final = output.Replace(" kW", "");
if (final.Contains("W")) { final = final.Replace(" W", ""); watts = true; } else watts = false;
var finalb = final.Split ('.')[0];
if (watts) { finalb = "1"; }
return Int32.Parse(finalb);
}
void triggerLights(int status) {
if (status == 1 && !overwrite) {
List<IMyInteriorLight> lights = new List<IMyInteriorLight> ();
GridTerminalSystem.GetBlocksOfType<IMyInteriorLight>(lights);
List<IMyReflectorLight> spotlights = new List<IMyReflectorLight> ();
GridTerminalSystem.GetBlocksOfType<IMyReflectorLight>(spotlights);
for (int i = 0; i < lights.Count; i++) {
if (getPrefixBool(lights[i].CustomName)) {
lights[i].GetActionWithName ("OnOff_On").Apply(lights[i]);
}
}
for (int i = 0; i < spotlights.Count; i++) {
if (getPrefixBool(spotlights[i].CustomName)) {
spotlights[i].GetActionWithName("OnOff_On").Apply(spotlights[i]);
}
}
}
else
if (status == 0 && !overwrite) {
List<IMyInteriorLight> lights = new List<IMyInteriorLight> ();
GridTerminalSystem.GetBlocksOfType<IMyInteriorLight>(lights);
List<IMyReflectorLight> spotlights = new List<IMyReflectorLight> ();
GridTerminalSystem.GetBlocksOfType<IMyReflectorLight>(spotlights);
for (int i = 0; i < lights.Count; i++) {
if (getPrefixBool(lights[i].CustomName)) {
lights[i].GetActionWithName("OnOff_Off").Apply(lights[i]);
}
}
for (int i = 0; i < spotlights.Count; i++) {
if (getPrefixBool(spotlights[i].CustomName)) {
spotlights[i].GetActionWithName("OnOff_Off").Apply(spotlights[i]);
}
}
}
}
bool getPrefixBool (string name) {
if (usePrefix) {
if (name.StartsWith(prefix)) {
return true;
} else return false;
} else return true;
}
I haven't tried much at this point as I can't exactly code... I have found a couple lines but they don't seem to work.

Some rows remains in a DataGrid when deleting multiple rows

I have a WPF triggered (TextChanged) function which calls two other function whose subroutine deletes rows from a DataGrid object when certain conditions are met.
I have a feeling I might be encountering race conditions on the delete of multiple rows. When I place a MessageBox.Show("somethings'); in between the two functions, 2 rows from DataGrid are deleted as expected with the message box popping up in between delete actions.
deleteFunction("item1");
MessageBox.Show("something");
deleteFunction("item2");
However if I remove the MessageBox only the first function deletes a single row (item1)from DataGrid.
deleteFunction("item1");
deleteFunction("item2");
I have tried all sorts of ways to resolve this, Thread.Sleep(500) in between function calls, setting up a Queue to FIFO the requests, thread locking. async ... Nothing seems to work for me.
I'm not even sure it is actually a race condition issue anymore. I am starting to wonder if there is some Thread connection to the DataGrid object that the MessageBox is severing when invoked and releasing the control for another function to interact with.
Code below:
private void streamCode_TextChanged(object sender, TextChangedEventArgs e)
{
if (configurationSectionLoaded == true)
{
streamCodeAlphanumeric(streamCode.Text);
streamCodeIsChar128(streamCode.Text);
}
formEdited = true;
}
private bool streamCodeAlphanumeric(string value)
{
dataValidation dv = new dataValidation();
if (dv.isAlphanumeric(value))
{
streamCode.Background = Brushes.LightGreen;
editStreamcode.Background = Brushes.LightGreen;
editStreamcode.IsEnabled = true;
//MessageBox.Show("scE01 Deleting");
//q.Enqueue(new UILogDeleteQueue() { qEntryType = "scE01" });
try
{
UILogRemoveRow("scE01");
}
catch(Exception e)
{
MessageBox.Show(e.ToString());
}
return true;
}
else
{
editStreamcode.IsEnabled = false;
streamCode.Background = Brushes.LightPink;
UILogAddRow("scE01", "Stream Code", "Non-Alphanumeric Characters Detected!");
return false;
}
}
private bool streamCodeIsChar128(string value)
{
dataValidation dva = new dataValidation();
if (dva.isChar128(value))
{
streamCode.Background = Brushes.LightGreen;
editStreamcode.Background = Brushes.LightGreen;
editStreamcode.IsEnabled = true;
//MessageBox.Show("scE02 Deleting");
try
{
UILogRemoveRow("scE02");
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
return true;
}
else
{
editStreamcode.IsEnabled = false;
streamCode.Background = Brushes.LightPink;
UILogAddRow("scE02", "Stream Code", "Invalid Length Detected!");
return false;
}
}
Finally here is the delete row code:
private void UILogRemoveRow(string entryCode)
{
int rowCount;
rowCount = UILog.Items.Count;
if (rowCount > 0)
{
for (int i = 0; i < rowCount; i++)
{
DataGridRow row = (DataGridRow)UILog.ItemContainerGenerator.ContainerFromIndex(i);
var selectedItem = UILog.ItemContainerGenerator.ContainerFromIndex(i);
if (row != null)
{
UILogObject theItem = (UILogObject)row.DataContext;
if (theItem.entryType == entryCode)
{
UILog.Items.RemoveAt(i);
}
}
}
}
}
Any assistance would be greatly appreciated.
UPDATE: included UILogAddRow function
private void UILogAddRow(string entryCode, string entryIdentifier, string entryDetail)
{
bool itemExists = false;
int rowCount;
rowCount = UILog.Items.Count;
if (rowCount > 0)
{
for (int i = 0; i < rowCount; i++)
{
DataGridRow row = (DataGridRow)UILog.ItemContainerGenerator.ContainerFromIndex(i);
if (row != null)
{
UILogObject theItem = (UILogObject)row.DataContext;
if (theItem.entryType == entryCode)
{
itemExists = true;
}
}
}
}
else
{
//MessageBox.Show(rowCount.ToString());
}
if (itemExists != true)
{
UILog.Items.Add(new UILogObject() { entryType = entryCode, identifier = entryIdentifier, detail = entryDetail });
}
UILog.Items.Refresh();
}
instead of working with low-level container elements (DataGridRow), cast items to your known type, and then search and remove
private void UILogRemoveRow(string entryCode)
{
var item = UILog.Items.OfType<UILogObject>()
.FirstOrDefault(x => x.entryType == entryCode);
if (item != null)
UILog.Items.Remove(item);
}

Two Arrays have same values but do not returns equal

I want to compare two arrays and if all the values are the same i will do some stuff. I write a function like this to check is there any different value. If so return false.
bool Deneme ()
{
for (int i = 0; i < correctOnes.Length; i++) {
if(correctOnes[i] != cubeRotation[i].rotation.eulerAngles)
{
return false;
}
}
return true;
}
When I call the Deneme function it always return false. However, I check the array values in the console they are all same. Any ideas what is going on ?
Checking the console like that
for (int i = 0; i < correctOnes.Length; i++) {
Debug.Log ("Corrects: " + correctOnes[i]);
Debug.Log ("Cubes: " + cubeRotation[i].rotation.eulerAngles);
}
Console Photo:
The most likely reason for this is that eulerAngles is double, which means that it should not be compared with operator ==. Two numbers may look the same when printed, but they would compare as non-equal.
The trick here is to compare using Math.Abs(a-b) < 1E-8 method:
if(Math.Abs(correctOnes[i]-cubeRotation[i].rotation.eulerAngles) < 1E-8) {
...
}
Above, 1E-8 is a small number that represents the tolerance for comparing doubles for equality.
You can have a try with
bool Deneme ()
{
for (int i = 0; i < correctOnes.Length; i++) {
if (!Mathf.Approximately (correctOnes[i].magnitude, cubeRotation[i].rotation.eulerAngles.magnitude))
{
return false;
}
}
return true;
}
I posted the test scaffolding for completeness, but the linq query at line #35 should get you your pass/fail results.
class Ans34467714
{
List<double> correctOnes = new List<double>() { 22.7, 22.6, 44.5, 44.5, 44.5};
List<rotation> cubeRotation = new List<rotation>() { new rotation() { eulerAngles = 22.3 }, new rotation() { eulerAngles = 22.6 }, new rotation() { eulerAngles = 44.5 }, new rotation() { eulerAngles = 44.5 }, new rotation() { eulerAngles = 44.5 } };
public Ans34467714()
{
}
internal bool Execute(string[] args)
{
bool retValue = false;
if (Deneme())
{
Console.WriteLine("Pass");
}
else
{
Console.WriteLine("Fail");
}
return retValue;
}
internal bool Deneme()
{
return correctOnes.Where((var, index) => cubeRotation[index].eulerAngles == var).Count() == correctOnes.Count;
}
}
class rotation
{
public double eulerAngles {get; set;}
public rotation()
{
}
}

How to disable more than one NumericUpDown controls using one method?

i have a form with more than one NumericUpDown as controls to input answer. i want every input is true for an operation (multiplication, sum etc), NumericUpDown for that operation will be disable. i have used the code below (just for sum operation), but i think its not efficient because i have to make a method to check every operation.
private void IsSumTrue() {
if (add1 + add2 == sum.Value)
{
sum.Enabled = false;
}
}
private void IsDifferenceTrue()
{
if (add1 - add2 == difference.Value)
{
difference.Enabled = false;
}
}
private void IsProductTrue()
{
if (add1 * add2 == product.Value)
{
product.Enabled = false;
}
}
private void IsQuotientTrue()
{
if (add1 / add2 == quotient.Value)
{
quotient.Enabled = false;
}
}
anyone have idea how to make it more efficient with just a method for all operation?
below is my idea, but to check the value is true for every NumericUpDown i don't know how.
private void DisableIfValueIsTrue()
{
foreach(Control control in this.Controls)
{
NumericUpDown value = control as NumericUpDown;
// if(value [NEED HELP]
}
}
Considering your situtaion, you can set a tag for each NumericUpDown in design mode like this:
sum.Tag=1;
square.Tag=2;
etc
Then define some int variables:
int iSum=add1+add2;
int iSquare= //Whatever you want
etc
And finally loop through your controls this way:
foreach (NumericUpDown control in this.Controls.OfType<NumericUpDown>())
{
int intCondition = Convert.ToInt32(control.Tag) == 1
? iSum
: Convert.ToInt32(control.Tag) == 2
? iSquare
: Convert.ToInt32(control.Tag) == 3
? i3
: i4; //You should extend this for your 8 controls
control.Enabled = intCondition == control.Value;
}
OK! Second way I offer
Since you will have to always check 8 different conditions, you could simply forget about looping through the controls and just change your method like this:
private void DisableIfValueIsTrue()
{
sum.Enabled = add1 + add2 != sum.Value;
difference.Enabled= add1 - add2 != difference.Value;
product.Enabled= add1 * add2 != product.Value;
quotient.Enabled= (add2 !=0) && (add1 / add2 != quotient.Value);
//etc
}
I came across this while doing some research and would like to give my solution I used for my situation and hope it helps people. I needed minimum and maximum numbers for a calculation, so mine are named appropriately and I correlated these with some CheckBoxes. I used null in beginning of minimum and end of maximum to account for empty. I also had to create an event handler SubscribeToEvents() shown below.
In my load event for my form:
SubscribeToEvents();
_checkBoxs = new[] { cbXLight, cbLight, cbMedium, cbHeavy, cbXHeavy, cbXXHeavy, cbXXXHeavy };
_minimumsNumericUpDowns = new[] { null, nLightMin, nMediumMin, nHeavyMin, nXHeavyMin, nXXHeavyMin, nXXXHeavyMin };
_maximumsNumericUpDowns = new[] { nXLightMax, nLightMax, nMediumMax, nHeavyMax, nXHeavyMax, nXXHeavyMax, null };
then I created a method:
private void DisableNumericUpDowns()
{
// disable everything:
foreach (var n in _minimumsNumericUpDowns)
{
if (n != null)
n.Enabled = false;
}
foreach (var n in _maximumsNumericUpDowns)
{
if (n != null)
n.Enabled = false;
}
}
The event handler:
private bool _eventsSubscribed;
private void SubscribeToEvents()
{
if (_eventsSubscribed)
return;
_eventsSubscribed = true;
cbXXHeavy.CheckedChanged += CheckBox_NumericState;
cbXHeavy.CheckedChanged += CheckBox_NumericState;
cbXLight.CheckedChanged += CheckBox_NumericState;
cbHeavy.CheckedChanged += CheckBox_NumericState;
cbLight.CheckedChanged += CheckBox_NumericState;
cbMedium.CheckedChanged += CheckBox_NumericState;
cbXXXHeavy.CheckedChanged += CheckBox_NumericState;
}
Now I can used this to check when they are enabled and if they are greater than or less than 0 if needed in the method CheckBox:
private void CheckBox_NumericState(object sender, EventArgs e)
{
// disable everything
DisableNumericUpDowns();
// see if more than one checkbox is checked:
var numChecked = _checkBoxs.Count((cb) => cb.Checked);
// enable things if more than one item is checked:
if (numChecked <= 1) return;
// find the smallest and enable its max:
var smallest = -1;
for (var i = 0; i < _checkBoxs.Length; i++)
{
if (!_checkBoxs[i].Checked) continue;
if (_maximumsNumericUpDowns[i] != null)
{
_maximumsNumericUpDowns[i].Enabled = true;
}
smallest = i;
break;
}
// find the largest and enable its min:
var largest = -1;
for (var i = _checkBoxs.Length - 1; i >= 0; i--)
{
if (!_checkBoxs[i].Checked) continue;
if (_minimumsNumericUpDowns[i] != null)
{
_minimumsNumericUpDowns[i].Enabled = true;
}
largest = i;
break;
}
// enable both for everything between smallest and largest:
var tempVar = largest - 1;
for (var i = (smallest + 1); i <= tempVar; i++)
{
if (!_checkBoxs[i].Checked) continue;
if (_minimumsNumericUpDowns[i] != null)
{
_minimumsNumericUpDowns[i].Enabled = true;
}
if (_maximumsNumericUpDowns[i] != null)
{
_maximumsNumericUpDowns[i].Enabled = true;
}
}
}
So I can check each state as required:
I want to check if Extra Light is check:
// Extra Light
if (!cbXLight.Checked) return;
if (nXLightMax.Enabled == false)
{
_structCategoryType = XLight;
CheckStructureSheets();
}
else
{
if (nXLightMax.Value > 0)
{
_dMax = nXLightMax.Value;
_structCategoryType = XLight;
CheckStructureSheets();
}
else
{
MessageBox.Show(#"Extra Light Max cannot be zero (0)");
}
}
and next light checks both:
// Light
if (cbLight.Checked)
{
if (nLightMin.Enabled == false && nLightMax.Enabled == false)
{
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
if (nLightMin.Enabled && nLightMin.Value > 0)
{
if (nXLightMax.Enabled && nLightMin.Enabled && nLightMax.Enabled == false)
{
_dMin = nLightMin.Value;
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
if (nLightMax.Value > 0)
{
_dMin = nLightMin.Value;
_dMax = nLightMax.Value;
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
MessageBox.Show(#"Light Max cannot be zero (0)");
return;
}
}
}
else if (nLightMin.Enabled == false && nLightMax.Enabled)
{
if (nLightMax.Value > 0)
{
_dMax = nLightMax.Value;
_structCategoryType = Light;
CheckStructureSheets();
}
else
{
MessageBox.Show(#"Light Max cannot be zero (0)");
}
}
else
{
MessageBox.Show(#"Light Min cannot be zero (0)");
return;
}
}
}
Hope this helps someone.
Tim
thanks for #AlexJoliq and #BrettCaswell. just want to inform that before Alex edited his answer from using "==" to "!=", i (thought) already solved the problem. but i don't know where is the more effective and efficient way, alex's or mine.
below is my code for DisableIfValueIsTrue():
if (add1 + add2 == sum.Value) sum.Enabled = false;
if (add1 - add2 == difference.Value) difference.Enabled = false;
if (add1 * add2 == product.Value) product.Enabled = false;
if (add1 / add2 == quotient.Value) quotient.Enabled = false;

How to group an array of variables based on flags assigned to them with minimal code in C#

I have an array that has four elements
example :
int[] a = new int[5];
the value would be like : a[0] = 10,a[1]=5,a[2]=15,a[3]=10,a[4]=0;
I have flag ,
public bool[] flag = new bool[4]{false,false,false,false};
based on which I need to assign this above values to another variable named b[5].
If the flag is false,it will add to the existing values of b ,
else it will reset the values of a to b.
I have tried the following code which seems to be too lengthy
count[0]=20,count[1]=20;count[2]=20;count[3]=20;
flag[0]=true,flag[1]=true,flag[2]=true,flag[3]=false;
void display(int[] count,int[]flag)
{
if (flag[0] == true)
{
resetcount[0] = count[0];
}
if(flag[1]==true)
{
resetcount[1] = count[1];
}
if (flag[2] == true)
{
resetcount[2] = count[2];
}
if(flag[3]==true)
{
resetcount[3] = count[3];
}
if (flag[0] == false)
{
resetcount[0] += count[0];
}
if (flag[1] == false)
{
resetcount[1] += count[1];
}
if (flag[2] == false)
{
resetcount[2] += count[2];
}
if (flag[3] == false)
{
resetcount[3] += count[3];
}
}
here resetcount[0]=10,resetcount[1]=10,resetcount[2]=10,resetcount[3]=10;
if all flag is false the count value will be added and if it is true the count value will be set to reset count
so as above it will be 0,1,2
count[0]=20,count[1]=20;count[2]=20;count[3]=20;
flag[0]=true,flag[1]=true,flag[2]=true,flag[3]=false;
resetcount[0]=10,resetcount[1]=10,resetcount[2]=10,resetcount[3]=10;
so now resetcount would be :
resetcount[0]=20,resetcount[1]=20,resetcount[2]=20,resetcount[3]=30;
Like a loop?
count[0]=20,count[1]=20;count[2]=20;count[3]=20;
flag[0]=true,flag[1]=true,flag[2]=true,flag[3]=false;
void display(int[] count,int[]flag)
{
for (int i = 0 ; i<=3 ; i++)
{
if (flag[i])
{
resetcount[i] = count[i];
}
else
{
resetcount[i] += count[i];
}
}
public void Display(int[] resetCount, int[] count, bool[] flags)
{
for (int i = 0; i < resetCount.Count(); i++)
{
resetCount[i] = this.Calculate(resetCount[i], count[i], flags[i]);
}
}
public int Calculate(int resetCount, int count, bool flag)
{
if (flag)
{
resetCount = count;
}
else
{
resetCount += count;
}
return resetCount;
}

Categories

Resources