If-else statement with radio buttons and a for loop - c#

I've gotten an issue that keeps happening and I'm unsure what the problem is. I need to create a program in Microsoft Visual studio where radioButton1 is for finding the sum of consecutive numbers and radioButton2 is for finding the factorial of a number.
There will be three buttons, one for FOR loop, one for WHILE loop, and one for DO-WHILE loop. I'm working on the FOR button.
What I'm trying to do is by making a selection, then pressing one of the buttons, it'll find the answer using the loop clicked in a Message box.
This is what I've gotten so far:
private void button1_Click(object sender, System.EventArgs e)
{
if ((radioButton1.Checked == true) && (radioButton2.Checked == false))
{
int sum = 0;
int number = int.Parse(numericUpDown1.Value.ToString());
for (int i = 1; i <= number; i++)
{
sum = sum + i;
MessageBox.Show("The sum of the consecutive numbers leading up to " + number + " is " + sum + ".");
}
MessageBox.Show("The sum of the consecutive numbers leading up to " + number + " is " + sum + ".");
}
else if ((radioButton2.Checked == true) && (radioButton1.Checked == false))
{
int product = 1;
int number = int.Parse(numericUpDown1.Value.ToString());
for (int i = 1; i <= number; i++)
{
product *= i;
MessageBox.Show("The factorial of the numbers leading up to " + number + " is " + product + ".");
}
MessageBox.Show("The factorial of the numbers leading up to " + number + " is " + product + ".");
}
else
{
MessageBox.Show("Invalid");
}
}
I keep receiving this message:
"'Lab5'does not contain a definition for 'radioButton2.CheckedChanged' and no extension method 'radioButton2.CheckChanged' accepting a first argument of type 'Lab5' could be found (are you missing a using directive or an assembly reference?)."
And I honestly have no idea what that means.
Any help would be greatly appreciated.
I want to keep it in an if-else statement simply because I don't want the message box for radioButton1 to pop up when radioButton2 is selected.

You have probably inadvertently added a handler to that radio button (e.g. by double clicking it in the designer) and then removed it. When the solution is building, it is looking for that function but can't find it.
Check Lab5.Designer.cs for the radioButton2 code. It will look something like this:
this.radioButton1.AutoSize = true;
this.radioButton1.Location = new System.Drawing.Point(102, 162);
this.radioButton1.Name = "radioButton1";
this.radioButton1.Size = new System.Drawing.Size(85, 17);
this.radioButton1.TabIndex = 1;
this.radioButton1.TabStop = true;
this.radioButton1.Text = "radioButton1";
this.radioButton1.UseVisualStyleBackColor = true;
this.radioButton1.CheckedChanged += new System.EventHandler(this.radioButton1_CheckedChanged); /* THis is the offending line! */
That last line is trying to add an event handler referencing a non-existant method. You can either remove it here.
Also, when the program builds, you should be able to double-click on the compile error and the IDE will take you to the source of the problem.

Looks like a homework. Either way, you need to implement a handler for your radio buttons for the event CheckChanged. Also, if you put those radio buttons in a group, either one can be checked and in the checkchanged event you should populate some functionMode or something. Example, when RadioButton1 is checked, you should store a variable that'll contain which formula to apply, on the other one checked you should change that. And in the button submit event, use that variable to see the current mode and apply that formula.

Related

Second for loop isn't running inside my update

This if statement within the update() have 2 for-loop, but it only runs the first one after the if condition is activated, and I don't know why.
I'm building a code for path optimizing in unity. Currently I have to find out the path that came across the nodes/points/positions with a certain positions array that the index is the order the path should follow. Some path between 2 nodes are repeated , ex: A to B and B to A is consider the same path and shall thicken the width of line AB eventually rendered. So I tried to sort out the position array into 2 different array for comparing if any of the pair of nodes(or we can say line) is repeated. And I encountered a problem in if statement within the update().
The first should sort out the original array for later comparison. The second one is just for testing if the first one do their job. No comparing yet. However after hitting play and satisfy the if statement I can see all the Debug.log in the first one, everything is normal, the sorting is normal, while the second one just doesn't print anything at all.
I tried comment out the first one, and the second one will run.
I tried to put second one outside the if statement, after it, and without commenting the first one, the second one won't run.
I tried to put the second one before the first one, in the if statement, the second one will run and the first one won't.
So I think this might be some kind of syntax error or am I using the if statement wrong? Please help.
if (l > 0)//activate when we choose any preset processes
{
for (int n = 0; n <= positions.Length; n++)//this loop will sort all the pos1 and pos 2 into array for current frame
{
curPos_1 = positions[n];//current position of node 1
curPos_2 = positions[n + 1];
Debug.Log("CURPOS_1 of line number " + n + " is " + curPos_1);
Debug.Log("CURPOS_2 of line number " + n + " is " + curPos_2);
flag[n] = 0;
Pos_1[n] = curPos_1;
Pos_2[n] = curPos_2;
Debug.Log("POS_1 array of line number " + n + " is " + Pos_1[n]);
Debug.Log("POS_2 array of line number " + n + " is " + Pos_2[n]);
}
for (int o = 0; o <= positions.Length; o++)
{
Debug.Log("flag of number " + o + " is " + flag[o]);
}
}
As described, all for loop should print something. Not just one of it.
Have you checked your Unity Console Window ?
In your first loop you get the next item but its condition will fail at the end, i.e. off by one.
Correct code should be something like this:
var floats = new float[100];
for (var i = 0; i < floats.Length - 1; i++)
{
var f1 = floats[i];
var f2 = floats[i + 1];
}
Now, Unity, has a behavior of ON ERROR RESUME NEXT, so it's highly probable that an error has occured but you haven't seen it (did you turn off the red icon for toggling errors in console ?).
Also, for some conditions only you know about (you didn't post the whole context), it could work once after you've changed some state of your program.

I have multiple text boxes (tbVarName1, tbVarName2, ... tbVarName[n]) and I want to increment them in a for loop to assign the text to something

I have a multiple text boxes that I want to assign their string content to a variable however I'm not sure how to increment the text boxes. They are named, tbVarName1, tbVarname2, et cetera. Below is the for loop I have, right now I just have tbVarName1 hard coded in.
I have researched some of what other people have done and have only found tips for doing it in VB.
for(seriesIndex = 1; seriesIndex <= 4; seriesIndex++)
{
dataChart.Series["Variable " + seriesIndex].LegendText = tbVarName1.Text
}
At the end of this I would like the the legends to be updated to what's in the text boxes
Another way to do it is using the Controls collection from the Form (assuming that all TextBoxes are direct children of the form)
var ctrl = this.Controls.OfType<TextBox>();
for(seriesIndex = 1; seriesIndex <= 4; seriesIndex++)
{
TextBox t = ctrl.FirstOrDefault(c => c.Name == "tbVarName" + i);
if(t != null) dataChart.Series["Variable " + seriesIndex].LegendText = t.Text;
}
This will not require an array but you could end with a bigger loop if you have many controls of type textbox and it is not worth the effort if the TextBox are children of different containers (panels, groupboxes)
There are various ways to do this, one way is to add the controls into an array, for example:
var controls = new [] { tbVarName1, tbVarName2, tbVarName3 };
And now you can access them by index:
for(seriesIndex = 1; seriesIndex <= 4; seriesIndex++)
{
dataChart.Series["Variable " + seriesIndex].LegendText = controls[seriesIndex - 1].Text;
// ^^^^^^^^^^^^^^^^^^^^^^^^^
// Like this
// Note: arrays start at zero
}

If statement in Calculator

I'm a beginner programmer designing a calculator in Visual Studio 2013 using C#. I've run into a slight problem that I can't seem to fix. When I click on the square root button, I want the program to display the square root in the text box, as well as show what's happening in the label.
For example, if I want to calculate 9 + sqrt(16), I need to click 9 + 16, then press the square root button. The label above the text box should show "9 + sqrt(16)" and the text box itself should say "4". This all works like it should. But if I then take the square root of 4, I want the label to say "9 + sqrt(4)". I tried storing the first part (9 + ) as a string, but when the square root button is pressed twice, it displays "9 + sqrt(16) sqrt(4)".
Is there a different way to fix this or am I doing something wrong?
Here's part of the code I tried (result is the text box and expression is the label):
private void sqrt_Click(object sender, EventArgs e)
{
bool square_root_pressed = false;
string exp = "";
Button b = (Button)sender;
double res = Convert.ToDouble(result.Text);
if ((equal_pressed) || (operation == ""))
{
if (b.Text == "√")
{
result.Text = Convert.ToString(Math.Sqrt(res));
expression.Text = "sqrt(" + Convert.ToString(res) + ") =";
}
else
{
result.Text = Convert.ToString(Math.Sqrt(res));
if (square_root_pressed)
{
expression.Text = exp + " sqrt(" + Convert.ToString(res) + ")";
}
else
{
exp = expression.Text;
expression.Text = expression.Text + " sqrt(" + Convert.ToString(res) + ")";
square_root_pressed = true;
}
}
the local variable square_root_pressed is always set to false when the event handler is called. The statement
expression.Text = exp + " sqrt(" + Convert.ToString(res) + ")";
will never be reached.
Try to store the state of keys pressed outside of the event handler.
you can add another event handler for "square root" and double the number when the Event is called,
once you click on the sqrt_Click Event "res" calculated the correct sqrt number.
If i understand your question properly, when the square root button is pressed twice, the label display repeats sqrt. A possible solution is when the statement exp = expression.Text executes; check to see if the text sqrt already exists in the label. If so then remove it in-order to avoid duplication.
exp = expression.Text;
if (exp.Contains("sqrt"))
{ exp = exp.Remove(exp.IndexOf("sqrt")); }
expression.Text = exp + " sqrt(" + Convert.ToString(res) + ")";
square_root_pressed = true;
I would suggest a totally different approach: I'd store the entire term as a list of objects and write a method to visualize them.
An example for what I mean could be the following:
public class Operation
{
public string Operator;
}
public class Function
{
public string Functor;
public List<object> Term;
}
These two classes would be my little helpers. Now if the user presses only numbers and operators, you can fill a list of term items like this:
public List<object> term = new List<object>();
...
term.Add(3);
term.Add(new Operation() { Operator = "+" });
term.Add(4);
This would be the equivalent of 3+4.
If the user presses the SQRT button, you could do this:
// Get the last element in the term and remove it
object o = term[term.Count - 1];
term.RemoveAt(term.Count - 1);
// Wrap the element in a function
Function f = new Function() { Functor = "SQRT" };
f.Term = new List<object>();
f.Term.Add(o);
// Add the function as new element to the term
term.Add(f);
This would turn the list from
3
+
4
into
3
+
SQRT
4
Similarly, if the user presses SQRT again, you can remove the function:
// Get the last element in the term and remove it
object o = term[term.Count - 1];
term.RemoveAt(term.Count - 1);
// Add the function term as new element to the term
term.AddRange((o as Function).Term);

Method to remove text boxes from panel

I have a method in a windows form application that tries to remove 2 text boxes from a panel.
In the method, I loop through all the controls in the panel. There are always supposed to be 2 panels removed and added together, but when removing, it randomly removes 1 or 2 containers when I press the button.
Here is the code to remove the textboxes:
private void removeRows()
{
string descName = "Desc" + (textBoxCounter - 1).ToString();
string costName = "Cost" + (textBoxCounter - 1).ToString();
if (textBoxCounter >= 0)
{
foreach (Control c in costItems.Controls)
{
if (c.Name == descName)
{
// Remove the control from the panel and dispose of it
panel.Controls.Remove(c);
c.Dispose();
}
if(c.Name == costName)
{
// Remove the control from the panel and dispose of it
panel.Controls.Remove(c);
c.Dispose();
}
}
// Decrement the counter
// This happens only once since two controls need to be removed
if (textBoxCounter == 0)
textBoxCounter = 0;
else
textBoxCounter--;
}
else
MessageBox.Show("There are no more rows to remove", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
testlabel1.Text = textBoxCounter.ToString();
testlabel2.Text = panel.Controls.Count.ToString();
}
Here is the code to add a button:
private void addRows(string desc, string cost)
{
if (textBoxCounter >= maxExpenses)
{
MessageBox.Show("Maximum number of expenses entered", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
TextBox Desc = new TextBox();
TextBox Cost = new TextBox();
// Give the text boxes names
Desc.Name = "Desc" + textBoxCounter.ToString();
Cost.Name = "Cost" + textBoxCounter.ToString();
// Format the text boxes
Desc.Width = panel.Width / 2;
Cost.Width = panel.Width / 4;
// Add the items to the costItems panel
panel.Controls.Add(expenseDesc);
panel.Controls.Add(expenseCost);
// Add the items to the expenses dictionary
panel.Add(Desc, Cost);
// Increment the text box counter variable
textBoxCounter++;
testlabel1.Text = textBoxCounter.ToString();
testlabel2.Text = costItems.Controls.Count.ToString();
}
}
Some info to know.
There will always be 2 textboxes added and removed, they relate to each other.
The textBoxCounter is initialized to 0, so the first two boxe names will be "Desc0" and "Cost0".
When I press the button to remove rows the first time, one text box is removed, and then if i press it again it might remove 2, it might only remove 1.
I tried debugging and I noticed that the foreach loop that iterates over all the controls in the panel seems to loop one time short of the full number of controls.
Any help with my code would be great.
Your problem is caused by the foreach, modifying the collection in foreach may cause some unexpected behavior. You just want to remove the TextBoxes with names being known beforehand, so why not using the method ControlCollection.RemoveByKey?
If you want to remove the last added textBoxes (Desc... and Cost...) do this:
panel.Controls.RemoveByKey(descName);
panel.Controls.RemoveByKey(costName);
If you want to remove all the added textBoxes (suppose you have other kinds of TextBoxes, otherwise we can use a little LINQ to remove all the textboxes easily):
for(int i = 0; i < textBoxCounter; i++){
panel.Controls.RemoveByKey("Desc" + i);
panel.Controls.RemoveByKey("Cost" + i);
}
Your code has two problems: you are disposing something you cannot dispose and you are iterating through a collection (which you are modifying) in the wrong way. You can delete all the Controls by doing:
panel.Controls.Clear();
Or iterating backwards by relying on the indices:
for (int i = panel.Controls.Count - 1; i >= 0; i--)
{
panel.Controls.RemoveAt(i);
}
Regarding the Dispose, you can use it if you wish but don't need to use Remove:
for (int i = panel.Controls.Count - 1; i >= 0; i--)
{
panel.Controls[i].Dispose();
}
PS: I asked something identical to this and got -6. One of the reasons for maintaining this question was precisely being helpful to others (I saw the code you are using to delete controls in internet and I knew that quite a few people were using it). Pretty ironical, indeed.

Outlook.Items Restrict() weird behavior

I just want to filter my Mails with the Restrict-Method like so:
restriction += "[ReceivedTime] < '" + ((DateTime)time).ToString("yyyy-MM-dd HH:mm") + "'";
var count = oFolder.Items.Restrict(restriction).Count;//Cast<object>().ToList();
for (int i = 0; i < count; i++)
{
var crntReceivedTime = ((OutLook.MailItem)oFolder.Items.Restrict(restriction).Cast<object>().ToList()[i]).ReceivedTime;
if (crntReceivedTime > time)
{
string t = "";
}
}
Theoretically the line string t = ""; should never be called, because I determined the Items to never have entries which ReceivedTime's value is bigger than time.
The problem is the line gets called, what means the restricted Items Collection contains entries which its shouldn't contain.
Did I do something wrong or is the Restrict()-method just failing?
Firstly, you are using multiple dot notation. You are calling Restrict (which is expensive even if it is called once) on each step of the loop. Call it once, cache the returned (restricted) Items collection, then loop over the items in that collection.
Secondly, what is the full restriction? You are using += to add an extra restriction on ReceivedTime. What is the actual value of the restriction variable?
Edit: I had no problem with the following script executed from OutlookSpy (I am its author - click Script button, paste the script, click Run):
restriction = " [ReceivedTime] < '2011-06-11 00:00' "
set Folder = Application.ActiveExplorer.CurrentFolder
set restrItems = Folder.Items.Restrict(restriction)
for each item in restrItems
if TypeName(item) = "MailItem" Then
Debug.Print item.ReceivedTime & " - " & item.Subject
End If
next

Categories

Resources