I wrote this program using Arrays in C#. It's homework. I pretty much have everything written in the program but I am stuck on clearing the array. I thought I had it but I don't understand where it's not working.
The program is pretty straightforward. The user enters a score and hits the "add" button. Then the user can enter more scores (anything 0 to 100). If the user chooses "Display" the program will sort the entered scores and display them in a messagebox (done)
if the user presses the "Clear Scores" button the program should clear out the scores. I have it written to clear the text boxes, and I also wrote in there "Scores.Clear();" (Scores being the name of my list array) and then I returned the focus back to my scores entry text box so the user can enter another score.
The book I am using simply says to clear type NameOfList.Clear(); so I'm stuck on why it's not clearing. I can tell it isn't because if I type more scores it will add the total instead of restarting.
Here is my full program code. My clear starts about halfway down.
Thank you in advance.
{
public partial class frmScoreCalculator : Form
{
//declare a list array for scores
List<int> Scores = new List<int>();
//set total and average to 0
int Total = 0;
decimal Average = 0;
public frmScoreCalculator()
{
InitializeComponent();
}
//calculate the average by dividing the sum by the number of entries
private decimal CalculateAverage(int sum, int n)
{
Average = sum / n;
return Average;
}
private void frmScoreCalculator_Load(object sender, EventArgs e)
{
}
//closes the program. Escape key will also close the program
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
//clears the text boxes, clears the array, returns focus back to the score text box like a boss.
private void btnClear_Click(object sender, EventArgs e)
{
txtScore.Text = "";
txtCount.Text = "";
txtTotal.Text = "";
txtAverage.Text = "";
Scores.Clear();
txtScore.Focus();
}
//makes sure the score is within the valid range, calculates the average, adds to the number of
//scores entered, and adds to the total
private void btnAdd_Click(object sender, EventArgs e)
{
if (txtScore.Text == string.Empty)
{
txtScore.Focus();
return;
}
int Score = int.Parse(txtScore.Text);
if (Score > 0 && Score < 100)
{
Scores.Add(Score);
Total += Score;
txtTotal.Text = Total.ToString();
txtCount.Text = Scores.Count.ToString();
Average = CalculateAverage(Total, Scores.Count);
txtAverage.Text = Average.ToString();
txtScore.Text = string.Empty;
txtScore.Focus();
}
// if number is not valid, ask user for valid number
else
{
MessageBox.Show("Please enter a number between 0 and 100.", "ENTRY ERROR, DO IT RIGHT!");
}
// returns focus to txtNumber
txtScore.Focus();
txtScore.Text = "";
}
//display button
private void btnDisplay_Click(object sender, EventArgs e)
{
//sorts the scores low to high
Scores.Sort();
//displays scores in message box
string DisplayString = "Sorted Scores :\n\n";
foreach (int i in Scores)
{
DisplayString += i.ToString() + "\n";
}
MessageBox.Show(DisplayString);
}
}
}
You need to zero the variable Total at the same time as clearing the array.
Related
I am creating a C# application that generates two random integers,between 100 to 500. The numbers should perform addition such that
247 + 129 = ?
The form has a text box for the user to enter the problem's answer. When a button is clicked, the application should do the following:
Check the user's input and display a message indicating whether it is the correct answer or not.
Generate two new random numbers and display them in a new problem on the form
add a button named "Save score to file".
When clicked, this button should write the total number of problems, the number of correct answers as well as the percentage of problems answered correctly.
Code:
InitializeComponent();
Random rand = new Random();
{
int number1;
number1 = rand.Next(400) + 100;
numberLabel1.Text = Convert.ToString(number1);
}
{
int number2;
number2 = rand.Next(400) + 100;
numberLabel2.Text = Convert.ToString(number2);
}
}
private void checkButton_Click(object sender, EventArgs e)
{
int correctAnswer;
correctAnswer = int.Parse(numberLabel1.Text) + int.Parse(numberLabel2.Text);
int userAnswer;
userAnswer = Convert.ToInt32(userInputBox.Text);
if (userAnswer == correctAnswer)
{
MessageBox.Show("Your Answer is Correct");
}
else
{
MessageBox.Show("Your Answer is Incorrect");
}
}
private void clearButton_Click(object sender, EventArgs e)
{
numberLabel1.Text = "";
numberLabel2.Text = "";
userInputBox.Text = "";
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Close();
}
private void answerBox_TextChanged(object sender, EventArgs e)
{
}
}
}
The question I have is: How do I get an output? The message box isn't showing and I answer the problem correctly each time. After This how do Generate two new random numbers and display them in a new problem on the form add a button named "Save score to file".
When clicked, this button should write the total number of problems, the number of correct answers as well as the percentage of problems answered correctly.
private static Random rand = new Random();
private void checkButton_Click(object sender, EventArgs e)
{
int num1 = rand.Next(400) + 100;
int num2 = rand.Next(400) + 100;
label1.Text = num1.ToString();
label2.Text = num2.ToString();
int correctAnswer = num1 + num2;
int userAnswer = Convert.ToInt32(textBox1.Text);
if (userAnswer == correctAnswer)
{
MessageBox.Show("Your Answer is Correct");
}
else
{
MessageBox.Show("Your Answer is Incorrect");
}
}
[First]
Console.WriteLine ( String.Format("Answer => " + userAnswer ) );
will show it on console window
MessgeBox.Show( ( String.Format("Answer => {0}", userAnswer ) );
will show it on MessageBox.
I put 2 types of how to use String.Format for you :)
[Second]
you can make a button which do the task again.
put your generating code under the button function
[Third]
You need to study about StreamWriter
I am trying to make my button take input from a textbox and add it to the index. The problem is that with everything I have tried, I cannot get it to give a unique value to each position in the index.
private void addBtn_Click(object sender, EventArgs e)
{
for (int i = 0; i < nums.Length; i++)
{
if (nums[0] == 0)
{
nums[0] = int.Parse(inputText.Text);
i++;
}
if (nums[1] == 0)
{
nums[1] = int.Parse(inputText.Text);
i++;
}
}
MessageBox.Show(nums[i].ToString());
}
Right now my code inserts the value to both index positions instead of assigning a value to position 0 and then allowing the user to insert a different value into position 1 and so on and so on.
It's not clear what your intent is, but it looks like you might be trying to add numbers to an array. This code will assign the parsed string to the first item in the array that isn't zero.
private void addBtn_Click(object sender, EventArgs e)
{
int i = 0;
for (; i < nums.Length; i++)
{
if (nums[i] == 0)
{
nums[i] = int.Parse(inputText.Text);
break;
}
}
MessageBox.Show(nums[i].ToString());
}
But this would be a better way, because the user might type "0":
private int _lastUsedIndex = -1;
private void addBtn_Click(object sender, EventArgs e)
{
var number = int.Parse(inputText.Text);
// Increment by one
++_lastUsedIndex;
nums[_lastUsedIndex] = number;
MessageBox.Show(number.ToString());
}
But still, arrays aren't a great idea: They can't grow as you add things. First they're bigger than you need, then suddenly they're too small and you crash. We have better options now. Unless your teacher insists that you must use an array, use List<int> instead. In this version, we'll also use a different way to parse the number, which won't crash if the user types "LOLWUT?!?!" instead of a number:
private List<int> nums = new List<int>();
private void addBtn_Click(object sender, EventArgs e)
{
int number;
if (int.TryParse(inputText.Text, out number))
{
nums.Add(number);
MessageBox.Show(number.ToString());
}
else
{
MessageBox.Show(inputText.Text + " isn't a number, smart guy.");
}
}
I am supposed to get values entered into a text box, then display the total of the entered values, the average of the values, and the count of how many values have been entered.
So far I have coded:
List<int> intScoreList = new List<int>(20);
decimal decScoreAverage = 0m;
decimal decScoreTotal = 0m;
private void btnAdd_Click(object sender, EventArgs e)
{
int intScore = Convert.ToInt32(txtScore.Text);
int intScoreCount = 0;
intScoreList.Add(intScore);
for (int i = 0; i < intScoreList.Count; i++)
{
intScoreList[0] = intScore;
decScoreTotal += intScoreList[i];
intScoreCount++; //correct
decScoreAverage = decScoreTotal / intScoreCount; //correct
}
When I enter test values of 30 then 40, the total gives me 110 (30 + 40 * 2) rather than 70 (30 + 40). Where am I going wrong?
Use Linq. On the add button click event simply add the parsed value. Then display the Avg, and Count.
List<decimal> scoreList = new List<decimal>();
private void btnAdd_Click(object sender, EventArgs e)
{
decimalnum;
if (decimal.TryParse(txtScore.Text, out num))
{
scoreList.Add(num);
}
// Assign to count label Text property = scoreList.Count;
// Assign to average label Text property = scoreList.Average();
}
Now imagine the ability to reset all the user's input:
private void btnReset_Click(object sender, EventArgs e)
{
scoreList.Clear();
}
Utilizing the list instance you can easily add number's as entered and correctly parsed from the user. The Average Linq extension method will do all the math for you, no need to do it yourself.
To the commenters' (justified) point below, here's some more explanation.
You're total isn't computing correctly mainly because you are changing the first item of your recorded values: intScoreList[0] = intScore;. By altering it, you are interfering with the sum.
A much clean operation consists of adding your new data to the array and recomputing the sum.
List<int> intScoreList = new List<int>(20);
decimal decScoreAverage = 0m;
decimal decScoreTotal = 0m;
private void btnAdd_Click(object sender, EventArgs e)
{
int intScore = Convert.ToInt32(txtScore.Text);
int intScoreCount = 0;
intScoreList.Add(intScore);
decScoreTotal = 0;
foreach(int i in intScoreList) {
decScoreTotal += i;
}
decScoreAverage = decScoreTotal / intScoreList.Count;
intScoreCount = inScoreList.Count;
}
Note that this isn't necessarily the most efficient implementation since as the number of values increase, the foreach loop will get more and more expensive. A better approach is to keep track of the current total and average and adjust them with the new value (which you can still add to the list for other purposes if you need).
The average is computed this way:
New_average = old_average * (count-1)/count + new_value /count
And here's the new code:
List<int> intScoreList = new List<int>(20);
decimal decScoreAverage = 0m;
decimal decScoreTotal = 0m;
private void btnAdd_Click(object sender, EventArgs e)
{
int intScore = Convert.ToInt32(txtScore.Text);
int intScoreCount = 0;
intScoreList.Add(intScore);
intScoreCount = inScoreList.Count;
decScoreTotal += intScore;
decScoreAverage = decScoreAverage * (intScoreCount- 1)/intScoreCount + intScore/intScoreCount;
}
Since the loop adds up all the items,
dont' you want
decScoreTotal = 0
before your for loop?
I am trying to get the counter named "Guesses" to keep a tally of attempts at guessing a random number and output the total attempts at guessing the number. I have tried leaving the counter declaration at 0 and 1 and the number of attempts to guess is always 0 or 1. Help would be appreciated and I will re-post entire working code once it's figured out. Here is my code.
int Answer; // declares the Answer variable outside button event
public frmGuess()
{ // generates random number outside button event so does not change on button click
InitializeComponent();
Random rand = new Random();
Answer = rand.Next(100) + 1; // makes it range 1 to 100
}
private void btnGuess_Click(object sender, EventArgs e)
{
int UserGuess;
int Guesses = 0; // start counter
if (string.IsNullOrEmpty(txtGuess.Text)) // input validation check to make sure not blank and is a whole number integer
{
MessageBox.Show("Please enter a whole number between 1 and 100");
return;
}
else
{
UserGuess = int.Parse(txtGuess.Text); // variable assign and code run
Guesses ++;
if (UserGuess > Answer)
{
txtGuess.Text = "";
lblAnswer.Text = "Too high, try again.";
}
else if (UserGuess < Answer)
{
txtGuess.Text = "";
lblAnswer.Text = "Too low, try again.";
}
else
{
lblAnswer.Text = "Congratulations the answer was " + Answer + "!\nYou guessed the number in " + Guesses + " tries.\nTo play again click the clear button."; //victory statement
}//end if
} //end if
}
private void btnClear_Click(object sender, EventArgs e) // clears Answer label and Guess textbox
{
txtGuess.Text = "";
lblAnswer.Text = "";
}
private void btnExit_Click(object sender, EventArgs e) // closes window
{
this.Close();
}
}
}`
Yes indeed! That took care of it. To think I placed the random number outside the button click but didn't do it to the counter - foolishness. Thanks all! Working code is :
{
int Answer; // declares the Answer variable outside button event
int Guesses = 0; // declares counter outside button event
public frmGuess()
{ // generates random number outside button event so does not change on button click
InitializeComponent();
Random rand = new Random();
Answer = rand.Next(100) + 1; // makes it range 1 to 100
}
private void btnGuess_Click(object sender, EventArgs e)
{
int UserGuess;
if (string.IsNullOrEmpty(txtGuess.Text)) // input validation check to make sure not blank and is a whole number integer
{
MessageBox.Show("Please enter a whole number between 1 and 100");
return;
}
else
{
UserGuess = int.Parse(txtGuess.Text); // variable assign and code run
Guesses ++; // adds 1 to attempts but doesn't count textbox blank or mistyping
if (UserGuess > Answer)
{
txtGuess.Text = "";
lblAnswer.Text = "Too high, try again.";
Guesses++;
}
else if (UserGuess < Answer)
{
txtGuess.Text = "";
lblAnswer.Text = "Too low, try again.";
Guesses++;
}
else
{
lblAnswer.Text = "Congratulations the answer was " + Answer + "!\nYou guessed the number in " + Guesses + " tries.\nTo play again click the clear button.";
}//end if
} //end if
}
private void btnClear_Click(object sender, EventArgs e) // clears Answer label and Guess textbox
{
txtGuess.Text = "";
lblAnswer.Text = "";
}
private void btnExit_Click(object sender, EventArgs e) // closes window
{
this.Close();
}
}
}
`
You are resetting the counter in your click event.
int Answer; // declares the Answer variable outside button event
int Guesses = 0; // declare this outside button event, and initialize it to 0.
// initialization will happen when the Form object is created.
...
private void btnGuess_Click(object sender, EventArgs e)
{
int UserGuess;
// DO NOT reset the counter here. This line is the culprit that
// resets the counter every time you click the button
//int Guesses = 0; // start counter
...
}
...
It's a scoping issue. You currently define guesses within your event handler where it resets the counter with each button click. If you define it at the form level, even as a property or member variable, that scope will allow the variable to retain its value through multiple button click events.
Don't think i could be any newer to coding, so please forgive me for whats about to be asked.
Im currently writing a program that lets the user enter a desired amount of random numbers to be generated by Random via textBox (lets say 15 --> you get 15 random numbers), ranging from 1 to 1000.
When hitting the Button A, those randomized Numbers will be saved in Zahlenarray[](-->with the length of the number entered in the textbox) and displayed in label1.Text.
Then there's a Button B, that, when clicked, should sort the Numbers from Zahlenarray[] via bubblesort and display them in label2.
My problem is now that the second Method (Button B_Click) doesnt have the contents of Zahlenarray from the Button A_Click Method.
Id like to pass this data by ref via the arguments, but fiddling with public void (Object sender, EventArgs e) seems to get me in major trouble.
Can i add arguments after EventArgs e, ... or am i missing another way of getting data out f this "scope" (hope thats the right word)?
Both Methods are in the same class.
part of the code of Button A:
public void Button_Anzeigen_Click(Object sender, EventArgs e)
{
label1.Text = "";
int[] Zahlenarray = new int[Int32.Parse(textBox1.Text)];
Everything from Button B:
private void Button_Sortieren_Click(object sender, EventArgs e)
{
label2.Text = "";
label3.Text = "";
int Speicher;
for (int n = Zahlenarray.Length; n > 0; n--)
{
for (int i = 0; i < n-1; i++)
{
if (Zahlenarray[i] > Zahlenarray[i + 1])
{
Speicher = Zahlenarray[i];
Zahlenarray[i] = Zahlenarray[i + 1];
Zahlenarray[i + 1] = Speicher;
Speicher = 0;
}
}
}
foreach (int i in Zahlenarray)
{
label2.Text += i + " ";
if ((i % 9 == 0) && !(i == 0))
label2.Text += "\n";
}
}
Put your array declaration outside of your buttona click handler so you can reference it inside your button b handler.
int[] Zahlenarray;
public void Button_Anzeigen_Click(Object sender, EventArgs e)
{
label1.Text = "";
Zahlenarray = new int[Int32.Parse(textBox1.Text)];
...
}