Stack overflow with a loop c# - c#

I am currently having problems with this loop. It becomes an infinite loop and i get a stack overflow error. This is for a interest rate trade swap application. i is the length of the trade and l is the increasing index.
private void button1_Click(object sender, EventArgs e)
{
int outp = 0;
int i = int.Parse(tradeLength.Text);
string month = "January";
for (int l = 1; l <= i; l++)
{
Console.WriteLine("I iterated " + l + " Amount of times");
if (l == 1)
{
month = "January";
}
if (l == 2)
{
month = "February";
}
if (l == 3)
{
month = "March";
}
if (l == 4)
{
month = "Aprll";
}
if (l == 5)
{
month = "May";
}
if (l == 6)
{
month = "June";
}
if (l == 7)
{
month = "July";
}
if (l == 8)
{
month = "August";
}
if (l == 9)
{
month = "September";
}
if (l == 10)
{
month = "October";
}
if (l == 11)
{
month = "November";
}
if (l == 12)
{
month = "December";
}
else
{
month = "Null";
l = 1;
}

The cause is the final else:
if (l == 12) {
month = "December";
}
else { // <- if l != 12 (e.g. l == 1) restart the loop
month = "Null";
l = 1;
}
you want else if:
if (l == 1)
{
month = "January";
}
else if (l == 2)
{
...
}
...
else if (l == 12)
{
...
}
else {
month = "Null";
l = 1;
}
Edit: Another problem (see FKEinternet's comment) is a user input: if i is greater than 12 l never reaches it. You have to either validate the user input:
int i = int.Parse(tradeLength.Text);
if (i > 12)
i = 12; // or ask for other value
or use modular arithmetics:
for (int index = 1; index <= i; index++) {
int l = index % 12 + 1;
if (l == 1)
{
month = "January";
}
else if (l == 2)
...
else if (l == 12)
...
else
{
month = "Null";
l = 1;
}
}

It is not a very good idea to set the loop variable inside the loop. Like #stuartd pointed out, in your else line you set the loop variable to 1 and causing the loop to start all over again. Remove the l=1 line in your else block.

I presume you want to go to next year when i > 12. The way your code is made, when this happens, you get to loop forever, because "l" never reaches a number bigger than 12, it becomes 1 when it hits 13 and starts over.
To fix this, instead of
if (l == 1)
you want to use
if ((l % 12) == 1)
so your entire loop would be like this:
for (int l = 1; l <= i; l++)
{
Console.WriteLine("I iterated " + l + " Amount of times");
if ((l % 12) == 1)
{
month = "January";
}
if ((l % 12) == 2)
{
month = "February";
}
if ((l % 12) == 3)
{
month = "March";
}
if ((l % 12) == 4)
{
month = "Aprll";
}
if ((l % 12) == 5)
{
month = "May";
}
if ((l % 12) == 6)
{
month = "June";
}
if ((l % 12) == 7)
{
month = "July";
}
if ((l % 12) == 8)
{
month = "August";
}
if ((l % 12) == 9)
{
month = "September";
}
if ((l % 12) == 10)
{
month = "October";
}
if ((l % 12) == 11)
{
month = "November";
}
if ((l % 12) == 0)
{
month = "December";
}
{
PS = this is really not the right way to do this, I'm just using your own code and making the least amount of mods for it to work as intented. Good luck!

Related

How can do calculations inside a string?

How do i use operands in this code? What can i do to resolve this problem? Any suggestions or links to tutorials would be appreciated.
Operator '%' cannot be applied to operands of type 'string' 'int'
int i = 0;
double[] arr1 = new double[20];
for (i = 0; i < 20; i++)
{
Console.Write("Enter a number (0=stop): ");
var year = Console.ReadLine();
if (year == "0") break;
arr1[i] = int.Parse(year);
while (year != 0)
{
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
{
Console.WriteLine($"{year} is a leap year.");
}
else if (year < 0)
{
Console.WriteLine($"Year must be positive!");
}
else
{
Console.WriteLine($"{year} is not a leap year.");
}`
You are close. You are already parsing the string to an int. Just use that instead of the string year when doing your calculations. Also, I'm not sure what you're trying to do with that while loop but I don't think you need it. It seems to just cause your program to go in an infinite loop because while is evaluating year but there is no opportunity to change the year value within the while loop.
void Main()
{
int i = 0;
double[] arr1 = new double[20];
for (i = 0; i < 20; i++)
{
Console.Write("Enter a number (0=stop): ");
var line = Console.ReadLine();
int numYear = int.Parse(line);
arr1[i] = numYear;
string message = "" ;
if (line != "0")
{
if (numYear < 0)
{
message = "Year must be positive!";
}
else if ((numYear % 4 == 0) && (numYear % 100 != 0)) || (numYear % 400 == 0))
{
message = $"{numYear} is a leap year.");
}
else
{
message = $"{numYear} is not a leap year.");
}
Console.WriteLine(message);
}
}
}

Dynamically calculate waiting time in a queue

I have a method that calculates the waiting time in a queue. It works fine for a small range. However, you can quickly see that this would become very tedious to do with a large range. In this example, if you are #1 in the queue, your wait time is 'very soon'. If it's greater than 1 and less than 5: 0 to 1 weeks, and so on... How can I loop through this list to dynamically find the place in the queue?
if ((PlaceInQueue) <= 1)
{
result = "Very soon!";
}
if ((PlaceInQueue) > 1 & (PlaceInQueue) < 5)
{
result = "From 0 to 1 weeks.";
}
if ((PlaceInQueue) >= 5 & (PlaceInQueue) < 11)
{
result = "From 1 to 2 weeks.";
}
if ((PlaceInQueue) >= 11 & (PlaceInQueue) < 17)
{
result = "From 2 to 3 weeks.";
}
if ((PlaceInQueue) >= 17 & (PlaceInQueue) < 23)
{
result = "From 3 to 4 weeks.";
}
Here's what I've started and what I'm trying to accomplish. The first few if statements before the while loop may need to be hard coded as the math isn't exact and the rest would be dynamic. So, in this example, the results are correct up until the place in the queue is 11 or greater (inside the while loop).
int n = 1;
int max = 300; // Stop calculating when the max is reached
var PlaceInQue = (Convert.ToInt32(placeInQueue)); // This is the position in the Que
foreach (var item in PlaceInQue)
{
if (PlaceInQue <= 1)
{
result = "Very soon!";
}
if (PlaceInQue > 1 & PlaceInQue < 5)
{
result = "From 0 to 1 weeks.";
}
if (PlaceInQue >= 5 & PlaceInQue < 11)
{
result = "From 1 to 2 weeks.";
}
while (n < max)
{
if (PlaceInQue >= (should increment from 11 and then 17 then 23 then 29 and so on...) & PlaceInQue < (increment from 17 then 23 then 29 then 35 and so on...)
{
result = (should increment from "2 to 3 weeks" and then "3 to 4 weeks" and so on until max is reached...)
}
n++;
}
}
I think you need something like this:
if (PlaceInQue <= 1)
{
result = "Very soon!";
}
else if (PlaceInQue < 5)
{
result = "From 0 to 1 weeks.";
}
else if (PlaceInQue < 11)
{
result = "From 1 to 2 weeks.";
}
else if
{
for (int n = 11; n <= max; n += 5)
{
if (PlaceInQue >= n && PlaceInQue < n + 5)
{
int weeks = n / 5;
result = $"From {weeks} to {(weeks + 1)} weeks.";
break;
}
}
}
Below code works for me for which I have checked the probable edge cases. Let me know if it doesn't work for you.
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
Queue<int> queue = new Queue<int>(Enumerable.Range(1, 300));
foreach (var placeInQueue in queue)
{
if(placeInQueue <= 1)
Console.WriteLine($"Place: {placeInQueue}. Very soon!");
else if(placeInQueue < 300)
{
var fromTo = GetFromTo(placeInQueue);
Console.WriteLine($"Place: {placeInQueue}. From {fromTo.Item1} to {fromTo.Item2} weeks.");
}
}
}
private static Tuple<int,int> GetFromTo(int place)
{
if (place < 5)
return new Tuple<int, int>(0, 1);
var q1 = place / 5;
var q2 = 0;
if((place + 1) % 6 == 0)
{
q2 = (place + 1) / 6;
q1 = int.MaxValue;
}
else
q2 = (place/6) == 0 ? q1 : (place/6);
var from = Math.Min(q1, q2);
var to = from + 1;
return new Tuple<int, int>(from, to);
}
}

Simple Calendar with option for different months

Here's the prompt: Write a program
that prints a calendar for one month. Input
consists of an integer specifying the first
day of the month (1 = Sunday) and an
integer specifying how many days are
in a month.
Here is a sample output of what it should look like:
First day of the month 3
Number of days in the month 31
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
I've been working on it and here is what I have so far.
namespace Program_202t
{
class Program
{
static void Main(string[] args)
{
Console.Title = "Program 202t";
Console.Write("Enter the first day of the month: ");
int year = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the number of days in a month: ");
int month = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("\nSunday Monday Tuesday Wedsnesday Thursday Friday Saturday");
if (year == 1)
{
Console.SetCursorPosition(0, 4);
for (int i = 1; i <= 10; i++)
{
Console.Write(i + " ");
if (((i) % 7) > 0)
{
}
else
{
Console.Write("\n");
}
}
Console.Write("\b");
for (int b = 11; b <= month; b++)
{
if (((b) % 7) > 0)
{
Console.Write(b + " ");
}
else
{
Console.Write(b + "\n");
}
}
}
if (year == 2)
{
//Console.SetCursorPosition(10, 4);
for (int i = 1; i <= month; i++)
{
if (i == 1)
{
Console.Write(" " + i + " ");
}
else if (i > 1 && i < 11 && i != 6)
{
Console.Write(i + " ");
}
Console.Write("\b");
if (i == 6)
{
Console.Write(i + "\n");
}
if (i > 11 && i != 14)
{
Console.Write(i + " ");
}
if (i == 14)
{
Console.Write(i + "\n");
}
/*if (((i) % 6) > 0)
{
}
else
{
Console.Write("\n");
}
}
Console.Write("\b");
//FIX!!!
for (int b = 11; b <= month; b++)
{
if (((b) % 13) > 0 && b >13)
{
Console.Write(b + " ");
}
if (((b) % 20) > 0 && b <= 13)
{
Console.Write(b + " ");
}
else
{
Console.Write("\n");
}
}*/
}
if (year == 3)
{
Console.SetCursorPosition(20, 4);
for (int i = 1; i <= 10; i++)
{
Console.Write(i + " ");
if (((i) % 5) > 0)
{
}
else
{
Console.Write("\n");
}
}
Console.Write("\b");
for (int b = 11; b <= month; b++)
{
if (((b) % 7) > 0)
{
Console.Write(b + " ");
}
else
{
Console.Write("\n");
}
}
}
if (year == 4)
{
for (int i = 1; i <= 10; i++)
{
Console.Write(i + " ");
if (((i) % 7) > 0)
{
}
else
{
Console.Write("\n");
}
}
Console.Write("\b");
for (int b = 11; b <= month; b++)
{
if (((b) % 7) > 0)
{
Console.Write(b + " ");
}
else
{
Console.Write(b + "\n");
}
}
}
if (year == 5)
{
for (int i = 1; i <= 10; i++)
{
Console.Write(i + " ");
if (((i) % 7) > 0)
{
}
else
{
Console.Write("\n");
}
}
Console.Write("\b");
for (int b = 11; b <= month; b++)
{
if (((b) % 7) > 0)
{
Console.Write(b + " ");
}
else
{
Console.Write(b + "\n");
}
}
}
if (year == 6)
{
for (int i = 1; i <= 10; i++)
{
Console.Write(i + " ");
if (((i) % 7) > 0)
{
}
else
{
Console.Write("\n");
}
}
Console.Write("\b");
for (int b = 11; b <= month; b++)
{
if (((b) % 7) > 0)
{
Console.Write(b + " ");
}
else
{
Console.Write(b + "\n");
}
}
}
if (year == 7)
{
for (int i = 1; i <= 10; i++)
{
Console.Write(i + " ");
if (((i) % 7) > 0)
{
}
else
{
Console.Write("\n");
}
}
Console.Write("\b");
for (int b = 11; b <= month; b++)
{
if (((b) % 7) > 0)
{
Console.Write(b + " ");
}
else
{
Console.Write(b + "\n");
}
}
}
Console.ReadLine();
}
}
}
Do any of you know what I am doing wrong for the years that aren't 1? One works fine, but the rest have various problems.
Thanks for the help!
Will this do?
class Program
{
static void Main(string[] args)
{
Console.Title = "Program 202t";
Console.Write("Enter the first day of the month: ");
int startingDay = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter the number of days in a month: ");
int daysInMonth = Convert.ToInt32(Console.ReadLine());
List<string> daysOfTheWeek = new List<string>() {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
foreach (string day in daysOfTheWeek)
{
Console.Write($"{day,10}");
}
List<string> days = new List<string>();
for (int i = 0; i < startingDay; i++)
{
days.Add($"{"",10}");
}
for (int i = 1; i < daysInMonth+1; i++)
{
days.Add($"{i,10}");
}
for (int i = 0; i < days.Count; i++)
{
if (i%7!=0) {Console.Write(days[i]);}
else {Console.WriteLine(days[i]);}
}
}
Alrighty, i did a quick run through of the code and I see where you're issues are so I'll give you some tips on where to look.
For one, your code has logical issues revolving around the required formatting of the output. There are simpler ways to output the correct formatting. If you look at the .NET String Reference then look at formatting, you may find an easier way to do it.
Next, you have an issue with misaligned block endings so some of your code is never getting executed. I recommend you breakpoint your code at the first if statement and step through the code to understand the execution in runtime.
Lastly, I recommend clarifying your variable names a little bit. If the first input represent that day of the week, then perhaps use a variable name that represents it (for example dayOfWeek, but month doesn't do it for me). Also the number of days in the month could use a better variable name.
Please do ask questions if you need some more guidance. I'd be happy to help.

Can I execute only specific portion of nested if else in c#?

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

How can I change the name of the object in this case?

I want to make my own calendar with C#.
Because of that i want to create as much panels as the month has days.
I tried to do it with a for loop, but it doesn't work.
I think the problem is, that the name of the object never changes.
But how can I change the name of the object every time it loops through?
public void createPanel()
{
if (DateTime.Now.Month == 1 || DateTime.Now.Month == 3 || DateTime.Now.Month == 5 || DateTime.Now.Month == 7 || DateTime.Now.Month == 8 || DateTime.Now.Month == 10 || DateTime.Now.Month == 12)
{
for (int i = 0; i == 31; i++)
{
int locationX = 12;
int locationY = 74;
//Create Panel
Panel test = new Panel();
//Fill Panel
test.Name = "panel" + i;
test.Width = 200;
test.Height = 100;
test.BackColor = Color.White;
test.Location = new System.Drawing.Point(locationX, locationY);
this.Controls.Add(test);
test.Show();
if(i == 7 || i == 14 || i == 21)
{
locationY += 106;
locationX = 12;
}
locationX += 206;
}
}
for (int i = 0; i == 31; i++)
is wrong. You will never reach the inside of the for loop, since i is equal to 0 and expected to be 31.
Maybe you meant:
for (int i = 0; i <= 31; i++)
I'm assuming there's lots of other issues with your code, but fix this first and maybe open new and more specific questions.
Instead of hard coding the months in your if statement, you might want to use this instead:
DateTime.DaysInMonth(year, month);
So your loop should look something like:
var numDays = DateTime.DaysInMonth(selectedYear, selectedMonth);
for (int i = 0; i < numDays; i++)
{
// your code here
}
You can get the selected year and month from DateTime.Today, or just let the user select it for themselves.

Categories