increase variable value until condition is met C# - c#

Can't figure the good logic here I need to increase the value of my counter until the condition is met. but it says that the program is doing nothing here
int num;
int ctr = 3;
reqID = browser.Div(Find.ByClass("gwt-Label WNII") && Find.ByIndex(ctr)).OuterText;
bool isNumeric = int.TryParse(reqID, out num);
bool isTR = reqID.Contains("T_R_");
do { ctr++; }
while (isTR == true || isNumeric == true);
{
reqID = browser.Div(Find.ByClass("gwt-Label WNII") && Find.ByIndex(ctr)).OuterText;
}
Parsing this pages
https://hpe.wd5.myworkdayjobs.com/en-US/Jobsathpe/job/CBC01---Aruba-Cork-CBC01/Pricing-Specialist_1006905-3
https://hpe.wd5.myworkdayjobs.com/en-US/Jobsathpe/job/RYA01---Riyadh-Al-Faisaliah-Tower-RYA01/Portfolio-Sales-Specialist_1006892-1
See how many iterates of "gwt-Label WNII" class it has

You are not changing any of the variables that are your conditions inside the loop. So, the loop will either never start or never finish
You may want to order it like this:
int num;
int ctr = 3;
bool isTR = false;
bool IsNumeric = false;
do
{
reqID = browser.Div(Find.ByClass("gwt-Label WNII") && Find.ByIndex(ctr)).OuterText;
if(reqID != null)
{
isNumeric = int.TryParse(reqID, out num);
isTR = reqID.Contains("T_R_");
}
ctr++;
}
while (!isTR && !isNumeric);
do reference: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/do

Declare your bool outside of you while context and modify it inside :
int num;
int ctr = 3;
bool isNumeric = true;
bool isTR = true;
do
{
reqID = browser.Div(Find.ByClass("gwt-Label WNII") &&
Find.ByIndex(ctr)).OuterText;
isNumeric = int.TryParse(reqID, out num);
isTR = reqID.Contains("T_R_");
ctr++;
}
while (isTR == true || isNumeric == true);

Related

Unity crashes as the program goes through WaitForSeconds the last time

i have a strange problem. My Code works fine. Everything works as it should until it goes the last time through a foreach loop. The code:
public List<string> waveInput = new List<string>(); //die Eingabe der Welle als Zeichenfolge
public List<GameObject> enemyTyps = new List<GameObject>();
public List<Vector3> path = new List<Vector3>();
public GameObject tempPathStart;
public int currentWave = 0;
public int currentAmountOfEnemies;
private int spawnAmountOfEnemies;
private double spawnDelay;
private List<GameObject> enemyToSpawn = new List<GameObject>();
void Start() {
path.Add(tempPathStart.transform.position);
StartCoroutine(function());
}
IEnumerator function() {
while(waveInput.Capacity >= currentWave) {
if(waveInput[currentWave] == "" && currentAmountOfEnemies <= 0) {
currentWave++;
enemyToSpawn.Clear();
spawnAmountOfEnemies = 0;
} else if(currentAmountOfEnemies <= 0) {
string _substring = waveInput[currentWave].Substring(0, waveInput[currentWave].IndexOf(";") + 1);
ManageSubstring(_substring);
for(int i = 0; i < spawnAmountOfEnemies; i++) {
foreach(GameObject element in enemyToSpawn) {
this.SpawnEnemy(element);
yield return new WaitForSeconds((float)spawnDelay);
}
}
}
}
}
void ManageSubstring(string _substring) {
string _tempStringAmount = "";
string _tempStringDelay = "";
string _tempStringType = "";
bool _switchAmountDelay = false;
for(int i = 0; i < _substring.Length; i++) {
char c = _substring[i];
if(c >= '0' && c <= '9') {
if(_switchAmountDelay) {
_tempStringDelay += c;
} else {
_tempStringAmount += c;
}
} else if(c == ';') {
} else if(c == '.') {
_tempStringDelay += c;
} else {
_switchAmountDelay = true;
_tempStringType += c;
}
}
spawnDelay = double.Parse(_tempStringDelay);
spawnAmountOfEnemies = int.Parse(_tempStringAmount);
foreach(char c in _tempStringType) { //die Buchstaben in GameObjekte / Gegner umwandeln
int _tempConvertedInt = TranslateStringToInt(c);
enemyToSpawn.Add(enemyTyps[_tempConvertedInt]);
}
}
int TranslateStringToInt(char pToConvertChar) {
List<char> _alphabet = new List<char>() {'a','b','c','d','e','f','g','h','i','j','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
return _alphabet.IndexOf(pToConvertChar);
}
void SpawnEnemy(GameObject prefab) {
currentAmountOfEnemies++;
GameObject e = Instantiate(prefab) as GameObject;
e.transform.position = path[0];
}
the very strange thing as i already said is: the code works, even the line works fine until it goes through the last time. Then Unity crashes and i have no idea what i should do. If some more code is needed for context just say.
Thanks for every answer!
I just pulled your script into the debugger and stepped through the last iteration:
When the iteration is over, it goes back into the while() loop which encloses the whole body of function().
The while condition remains true since waveInput.Capacity is greater than the currentWave (still zero).
The if(waveInput[currentWave] == "" && currentAmountOfEnemies <= 0) is false since the waveInput[] array has an element zero which is not "", and the enemycount was not reset yet.
the else if(currentAmountOfEnemies <= 0) condition is also false since the current amount was not reset.
nothing more in the while-loop, nothing chagned, you have an endless-loop, which never hits a yield return. This locks up the Update() cycle of Unity and only allow killing.

How to store a variable by using a method in C#?

I have a few problems with the code below. I'm still learning and I don't know how to fix it.
1 .-What I'm trying to do is create a method (GetInt) to store variables like I'm trying to do in the second method (GetTrack) that will go into my main method.
2.-I can't get the GetInt method to loop when theres an invalid input, I'm guessing there's something wrong with the try/catch and boolean thingy
Thank you
//Get int Method
static public void GetInt(string sPrompt, int iMin, int iMax)
{
int iNum;
bool bError = false;
do
{
bError = true;
try
{
Console.Write(sPrompt);
iNum = int.Parse(Console.ReadLine());
if ((iNum < iMin) || (iNum > iMax))
{
Console.WriteLine("The value is out of range.");
bError = true;
}
}
catch (ArgumentException)
{
Console.WriteLine("An invalid number was entered, please try again.");
bError = true;
}
}
while (bError == false);
}
//Get Track Method
static public void GetTrack()
{
int iMin;
int iSec;
iMin = GetInt("Enter the minutes: ", 0, 10);
iSec = GetInt("Enter the seconds: ", 0, 59);
}
Immediately in the beginning of GetInt you set bError to true. This most likely should be false so you would actually loop since nowhere do you set it to false.
Also you don't return anything from the method so you don't get anything back. You have to change the method to return int and actually return the value when you get it.
The declaration of your GetInt method should be changed to the following:
//Get int Method
static public int GetInt(string sPrompt, int iMin, int iMax)
Remove the bError = true; statement from the beginning of your do...while loop.
After your do...while loop, add the following statement:
return iNum;
Also, your while condition should be changed from bError == false to bError == true or simply to bError, which means the same thing, if your intent is to keep prompting the user until the input is acceptable.
Here is how I "get" user input from the console:
string choice = string.Empty;
bool goodChoice = false;
while (!goodChoice)
{
Console.Clear();
Console.WriteLine(string.Empty);
Console.WriteLine("Do you really want to hurt me?");
Console.WriteLine(string.Empty);
Console.WriteLine(string.Empty);
Console.WriteLine("Please Y or N (or 0 to exit)");
choice = Console.ReadLine().Trim();
if (choice.Equals("Y", StringComparison.OrdinalIgnoreCase))
{
goodChoice = true;
}
if (choice.Equals("N", StringComparison.OrdinalIgnoreCase))
{
goodChoice = true;
}
if (choice.Equals("0"))
{
goodChoice = true;
return; /* exist the routine */
}
}
Modified for your case
string choice = string.Empty;
bool goodChoice = false;
while (!goodChoice)
{
Console.Clear();
Console.WriteLine(string.Empty);
Console.WriteLine("Enter an Integer between {0} and {1}", minValue, maxValue);
Console.WriteLine(string.Empty);
Console.WriteLine(string.Empty);
Console.WriteLine("Please enter an integer (or X to exit)");
choice = Console.ReadLine().Trim();
int intParseResult = 0;
bool intParseAttempt = int.TryParse(choice, out intParseResult);
if(!intParseAttempt)
{
goodChoice = false;
}
else
{
if ((intParseResult < minValue) || (intParseResult > maxValue))
{
Console.WriteLine("Out of Range");
}
else
{
goodChoice = true;
}
}
if (choice.Equals("X"))
{
goodChoice = true;
return -99999; /* you'll have to figure out how to handle exits on your own */
}
}

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;
}

Checking equality for two byte arrays

I am checking the equality of two byte arrays, and I wanted some help because what I have returns false even though the arrays should be equal.
Within my debug I could see both of a1 and b1 are equal, but it is not going inside the while loop to increment i.
public bool Equality(byte[] a1, byte[] b1)
{
int i;
bool bEqual;
if (a1.Length == b1.Length)
{
i = 0;
while ((i < a1.Length) && (a1[i]==b1[i]))
{
i++;
}
if (i == a1.Length)
{
bEqual = true;
}
}
return bEqual;
}
This always returns false: (a1[i]==b1[i]).
You need to add a return value somewhere. This should work:
public bool Equality(byte[] a1, byte[] b1)
{
int i;
if (a1.Length == b1.Length)
{
i = 0;
while (i < a1.Length && (a1[i]==b1[i])) //Earlier it was a1[i]!=b1[i]
{
i++;
}
if (i == a1.Length)
{
return true;
}
}
return false;
}
But this is much simpler:
return a1.SequenceEqual(b1);
Alternatively, you could use IStructuralEquatable from .NET 4:
return ((IStructuralEquatable)a1).Equals(b1, StructuralComparisons.StructuralEqualityComparer)
If performance is a concern, I'd recommend rewriting your code to use the Binary class, which is specifically optimized for this kind of use case:
public bool Equality(Binary a1, Binary b1)
{
return a1.Equals(b1);
}
A quick benchmark on my machine gives the following stats:
Method Min Max Avg
binary equal: 0.868 3.076 0.933 (best)
for loop: 2.636 10.004 3.065
sequence equal: 8.940 30.124 10.258
structure equal: 155.644 381.052 170.693
Download this LINQPad file to run the benchmark yourself.
To check equality you can just write:
var areEqual = a1.SequenceEqual(b1);
I'd recommend some short-circuiting to make things a bit simpler, and use of object.ReferenceEquals to short-circuit for cases when the arrays are the same reference (a1 = b1):
public bool Equality(byte[] a1, byte[] b1)
{
// If not same length, done
if (a1.Length != b1.Length)
{
return false;
}
// If they are the same object, done
if (object.ReferenceEquals(a1,b1))
{
return true;
}
// Loop all values and compare
for (int i = 0; i < a1.Length; i++)
{
if (a1[i] != b1[i])
{
return false;
}
}
// If we got here, equal
return true;
}
This should work:
public bool Equality(byte[] a1, byte[] b1)
{
if(a1 == null || b1 == null)
return false;
int length = a1.Length;
if(b1.Length != length)
return false;
while(length >0) {
length--;
if(a1[length] != b1[length])
return false;
}
return true;
}
You should add some return statements:
public bool Equality(byte[] a1, byte[] b1)
{
int i = 0;
if (a1.Length == b1.Length)
{
while ((i < a1.Length) && (a1[i]==b1[i]))
{
i++;
}
}
return i == a1.Length;
}
Or, better yet
public bool Equality(byte[] a1, byte[] b1)
{
if(a1.Length != b1.Length)
{
return false;
}
for (int i = 0; i < a1.Length; i++)
{
if (a1[i] != b1[i])
{
return false;
}
}
return true;
}

Mixed managed C++ method does not always return the same result to the calling C# code

A C++ method returns the correct value when I use a conditional breakpoint, but an incorrect value without a breakpoint.
C# method which calls C++:
bool SetProperty(Element element, Node referencePoint, List<Materializer> materializers, List<ulong> properties)
{
// Loop over STLs
for (int i = 0; i < materializers.Count; i++)
{
Materializer materializer = materializers[i];
if (materializer.IsPointInside(referencePoint.X, referencePoint.Y, referencePoint.Z, pentalTreeDatasets[i].top))
{
element.PropertyId = properties[i];
return true;
};
}
return false;
}
C++ methods in the header file:
int CountIntersects(double x, double y, double z, PentalTreeNode ^root)
{
Math3d::M3d rayPoints[2], intersectionPoint;
rayPoints[0].set(x,y,z);
rayPoints[1].set(x,y,1.0e6);
if(!root)
return 0;
else
{
int special = CountIntersects(x,y,z,root->special);
if (x <= root->xMax && x >= root->xMin && y <= root->yMax && y >= root->yMin)
{
if( _stlMesh->IsRayIntersectsPoly(root->index, rayPoints, intersectionPoint))
{
return (1 + special);
}
else
return special;
}
else
{
if (y>root->yMax)
{
return (CountIntersects(x,y,z,root->top)+special);
}
else if(y<root->yMin)
{
return (CountIntersects(x,y,z,root->bottom)+special);
}
else if(x<root->xMin)
{
return (CountIntersects(x,y,z,root->left)+special);
}
else if(x>root->xMax)
{
return (CountIntersects(x,y,z,root->right)+special);
}
else
return special;
}
}
}
bool IsPointInside(double x, double y, double z, PentalTreeNode ^root)
{
int intersectionCount = 0;
Math3d::M3d rayPoints[2], intersectionPoint;
rayPoints[0].set(x,y,z);
rayPoints[1].set(x,y,1.0e6);
if(_box->IsContainingPoint(x,y,z))
{
intersectionCount=CountIntersects(x,y,z,root);
return (intersectionCount%2!=0);
}
}
C++ methods in other header files:
bool IsRayIntersectsPoly(int nPolygonIndex, Math3d::M3d RayPoints[2], CVector3D& IntersectionPoint)
{
CMeshPolygonBase& Poly = m_PolygonArray[nPolygonIndex];
CArrayResultI Result;
int* pPolygonPoints = GetPolygonPoints(Poly, Result);
Math3d::MPlane TrianglePlane;
double Atmp[3], A;
CVector3D* pPoints[3];
pPoints[0] = &m_PointArray[*pPolygonPoints].m_Position;
for(int i = 1; i < Result.GetSize() - 1; i++)
{
pPoints[1] = &m_PointArray[*(pPolygonPoints+i)].m_Position;
pPoints[2] = &m_PointArray[*(pPolygonPoints+i+1)].m_Position;
TrianglePlane.Init(*pPoints[0], *pPoints[1], *pPoints[2]);
TrianglePlane.IntersectLine(RayPoints[0], RayPoints[1], IntersectionPoint);
A = GetTriangleArea(*pPoints[0], *pPoints[1], *pPoints[2]);
for(int j = 0; j < 3; j++)
{
Atmp[j] = GetTriangleArea(*pPoints[j], *pPoints[(j+1)%3], IntersectionPoint);
}
if( fabs(A - Atmp[0] - Atmp[1] - Atmp[2]) < 1.0e-5 ) return true;
}
return false;
};
double GetTriangleArea(CVector3D& T1, CVector3D& T2, CVector3D& T3)
{
double a, b, c, s;
a = (T1 - T2).length();
b = (T2 - T3).length();
c = (T3 - T1).length();
s = 0.5 * (a + b + c);
return( sqrt(s * (s - a)* (s - b)* (s - c)) );
}
When I start the program which calls SetProperty() within the for-loop, the results for some iterator values are wrong. When I set conditional breakpoints for critical iterator values in the for-loop and step over it, then the result is OK for that item. What may be the problem?
This is method in which I post breakpoint. For example, for critical element.Id==2393.
private void StartButton_Click(object sender, EventArgs e)
{
DateTime startTime = DateTime.Now;
List<Materializer> materializers = new List<Materializer>();
List<ulong> properties = new List<ulong>();
// Load STLs
for (int i = 0; (int)i < (this.dataGridView.RowCount - 1); i++)
{
if (dataGridView.Rows[i].Cells[1].Value != null && (string)dataGridView.Rows[i].Cells[1].Value != "")
{
Materializer materializer = new Materializer();
materializer.LoadSTLMesh(dataGridView.Rows[i].Cells[0].Value.ToString());
materializers.Add(materializer);
properties.Add((ulong)dataGridView.Rows[i].Cells[1].Tag);
}
}
CreatePentalTrees(materializers);
int processedElementCount = 0;
int changedElementCount = 0;
// Loop over elements
foreach (Element element in model.ElementsList.Values)
if ((element.Topology == 7 || element.Topology == 8) && !lockedProperties.ContainsKey(element.PropertyId)) // 3D elements only
{
Node center = this.CenterPoint(element, model.NodesList);
if (element.Id == 2393)
{
//if breakpoints thats ok, else not ok
Console.WriteLine(element.Id);
Console.WriteLine(element.PropertyId);
}
if (SetProperty(element, center, materializers, properties)) // Check for center point
{
//changedElements.Add(element.Id, true);
changedElementCount++;
}
else
{
// Check for all nodes if center point does not belong to any STL
int[] nodeOrder;
switch (element.Topology)
{
case 7:
nodeOrder = wedgeNodeOrder;
break;
case 8:
nodeOrder = brickNodeOrder;
break;
default:
throw new Exception("Unknown topology " + element.Topology.ToString());
}
for (int i = 0; i < nodeOrder.Length; i++)
{
Node node = model.NodesList[element.NodeIds[nodeOrder[i]]];
if (SetProperty(element, node, materializers, properties))
{
//changedElements.Add(element.Id, true);
changedElementCount++;
break;
}
}
}
if (++processedElementCount % 100 == 0)
{
labelTime.Text = "Changed/processed elements: " + changedElementCount.ToString() + "/" + processedElementCount.ToString();
labelTime.Refresh();
Application.DoEvents();
}
}
DateTime endTime = DateTime.Now;
labelTime.Text = "Total time: " + (endTime - startTime).TotalSeconds.ToString() + " s";
MessageBox.Show("Completed.");
SaveFileDialog saveFileDlg = new SaveFileDialog();
saveFileDlg.Title = "Save FEMAP neutral file";
saveFileDlg.Filter = "(*.neu)|*.neu";
if (saveFileDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
FemapNeutral.ExportNeu(saveFileDlg.FileName, model);
}
}
You seem to be calling a lot of methods you haven't listed, and/or the wall of code made me get lost. Adding that code won't help: reducing your problem to a simpler one that demonstrates the problem might.
However, the most likely cause of your problem, if you have unmanaged code reading managed data, is that you failed to marshal or pin the data prior to using the managed code.
Unpinned data can be moved around by the garbage collector in unexpected ways.

Categories

Resources