I have been trying to make a program in which, I add data of numbers but in texts, that these are added to a listbox and later make the sum of said values, only that they have explained to me that once the data has been added, now I must do a for loop to go through each data of the first array and thus be able to convert each one of them to a numeric value. Only when doing the conversion on the add button, it tells me that it is not in the correct format.
I declared the array in the public partial class like this: string [] array;
private void bt_capturar_Click(object sender, EventArgs e)
{
string datos = txb_numeros.Text;
arreglo = datos.Split(',');
lbx_elementos.Items.Clear();
foreach (string elementos in arreglo)
{
lbx_elementos.Items.Add(elementos);
}
}
private void bt_sumar_Click(object sender, EventArgs e)
{
int suma = 0;
for (int x = 0; x < arreglo.Length; x++)
{
int numero;
numero = int.Parse(arreglo[x]);
suma = suma + numero;
}
MessageBox.Show("La suma es igual a " + suma.ToString());
}
Often we query array with a help of Linq (note, that we use int.TryParse since some items can not represent any integer value)
using System.Linq;
...
private void bt_sumar_Click(object sender, EventArgs e)
{
int suma = arreglo.Sum(item => int.TryParse(item, out int v) ? v : 0);
MessageBox.Show($"La suma es igual a {suma}");
}
However, you can implement a simple loop:
private void bt_sumar_Click(object sender, EventArgs e)
{
int suma = 0;
foreach (string item in arreglo)
suma += int.TryParse(item, out int v) ? v : 0;
MessageBox.Show($"La suma es igual a {suma}");
}
Use Int32.TryParse instead
int numero;
bool success = Int32.TryParse(arreglo[x], out numero);
suma += success ? numero : 0;
If I understand correctly, you want to already validate the input or convert it in bt_capturar_Click?
In that case you can do the following:
private void bt_capturar_Click(object sender, EventArgs e)
{
string datos = txb_numeros.Text;
arreglo = datos
.Split(',')
.Select(Int32.Parse)
.ToArray();
// Or ignore invalid values:
//arreglo = datos
// .Split(',')
// .Select(s => Int32.TryParse(s, out int n) ? n : (int?)null)
// .Where(n => n != null)
// .ToArray();
lbx_elementos.Items.Clear();
foreach (string elementos in arreglo)
{
lbx_elementos.Items.Add(elementos.ToString()); // Maybe use AddRange?
}
}
private void bt_sumar_Click(object sender, EventArgs e)
{
MessageBox.Show("La suma es igual a " + arreglo.Sum());
}
}
Using the following simple code, you will resolve your problem easily.
string strInput = "1,2,3,4,5";
string[] arrInput = strInput.Split(',');
// convert a string array to an int array
int[] arrResult = Array.ConvertAll(arrInput, s => int.TryParse(s, out int t) ? t : 0);
// sum up an array of integers
int nSum = arrResult.Sum();
References:
Array.ConvertAll, int.TryParse, Enumerable.Sum
Related
E.g. If we have an array [1,2,3,4,6,7,8] then 1 then 2 then 3 then 4 are all consecutive but 6 is not, so that's the first non-consecutive number.
If the whole array is consecutive then return null .
The array will always have at least 2 elements 1 and all elements will be numbers. The numbers will also all be unique and in ascending order. The numbers could be positive or negative and the first non-consecutive could be either too. please help me finish this code i am new in programming. My code:
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _2katas
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var input = this.txtInput.Text;
var numarray = input.Split(',');
int firstValue = Convert.ToInt32(numarray[0]);
for (var i = 0; i < numarray.Length; i++)
{
if (Convert.ToInt32(numarray[i]) - i != firstValue)
{
lblPrint.Text = "";
}
else
{
lblPrint.Text = "";
}
if (this.rdbConsecutive.Checked == true)
{
lblKataRunning.Text = "Consecutive";
}
else if (this.rdbStripCleaning.Checked == true)
{
lblKataRunning.Text = "Strip Cleaning";
}
}
}
}
}
Let's extract a method:
Find the first element of an array that is not consecutive ...
If the whole array is consecutive then return null
We can implement it like this:
private static string FirstInconsecutive(string data) {
var array = data.Split(',');
if (array.Length <= 0)
return null; //TODO: what shall we return on empty array?
if (!int.TryParse(array[0], out int delta))
return array[0];
for (int i = 1; i < array.Length; ++i)
if (!int.TryParse(array[i], out int value) || value - i != delta)
return array[i];
return null;
}
Usage:
string result = FirstInconsecutive(txtInput.Text);
Please note int.TryParse which helps to return the right answer "ABC" on an input like "1, 2, 3, ABC, 4, 6, 7, 8" (user input txtInput.Text can contain any string)
A linq solution just for the fun of it:
static int? FindFirstNonConsecutive(IEnumerable<int> arr)
{
var nonConsecutiveInfo =
arr.Select((i, index) => new {Index = index, Delta = i - index})
.FirstOrDefault(t => t.Delta != arr.First());
return nonConsecutiveInfo?.Delta + nonConsecutiveInfo?.Index;
}
Note that this will only work finding non consecutive numbers in ascending order as per requirements.
Two numbers are not consecutive if the left ones + 1 <> the right one.
Check with something like this, note that you have to change your boundary checks:
for (var i = 0; i < numarray.Length - 1; i++)
{
if (Convert.ToInt32(numarray[i]) + 1 != Convert.ToInt32(numarray[i+1]))
Update your condition as below for loop and it will work. I would suggest you to have separate function so that it could be reusable if needed elsewhere in code.
Here start your loop from i = 1 and compare numarray[i-1] + 1 != numarray[i] values.
You can convert your sting[] to int[] with var numarray = input.Split(',').Select(x => Convert.ToInt32(x)).ToArray(); and use it with IsConsecutive(numarray) as per button1_Click code.
You can get first non-consecutive value with minor modification in return type and return statement as shown in GetFirstNonConsecutiveValue().
public bool IsConsecutive(int[] numarray)
{
for (int i = 1; i < numarray.Length; i++)
{
if (numarray[i-1] + 1 != numarray[i])
{
return false;
}
}
return true;
}
public int? GetFirstNonConsecutiveValue(int[] numarray)
{
for (int i = 1; i < numarray.Length; i++)
{
if (numarray[i-1] + 1 != numarray[i])
{
return numarray[i];
}
}
return null;
}
private void button1_Click(object sender, EventArgs e)
{
var input = this.txtInput.Text;
var numarray = input.Split(',').Select(x => Convert.ToInt32(x)).ToArray();
var nonConsecutiveValue = GetFirstNonConsecutiveValue(numarray);
if (nonConsecutiveValue != null)
{
// nonConsecutiveValue is first non consecutive value.
}
else
{
// sequence is consecutive.
}
}
One way to go.
string rawData = "1,2,3,4,6,7,8,9";
IEnumerable<int> data = rawData.Split(',').Select(v => Convert.ToInt32(v));
IEnumerable<int> all = Enumerable.Range(data.Min(), data.Max() - data.Min() + 1);
IEnumerable<int> diff = all.Except(data);
if (diff.Count() == 0)
{
return null;
}
return data.ElementAt(all.ToList().IndexOf(diff.First()))
NB Not thoroughly tested.
Just test diff for being empty to get the numbers are consecutive
I have 4 text boxes and i would like to find the largest number of the 4, what methods are there that isnt a loop, these text boxes are total scores from 4 teams, the last button is the box that will show the largest number
i have to enter each value (value 1 to 5) in each button, and the result is the largest number of the four, i will be making these values up
private void button1_Click(object sender, EventArgs e)
{
int value1 = 0;
int value2 = 0;
int value3 = 0;
int value4 = 0;
int value5 = 0;
int result = 0;
if (Int32.TryParse(textBox4.Text, out value1) && Int32.TryParse(textBox2.Text, out value2) && Int32.TryParse(textBox6.Text, out value3) && Int32.TryParse(textBox14.Text, out value4) && Int32.TryParse(textBox13.Text, out value5))
{
result = value1 + value2 + value3 + value4 + value5;
textBox21.Text = result.ToString();
}
}
private void button2_Click(object sender, EventArgs e)
{
int value1 = 0;
int value2 = 0;
int value3 = 0;
int value4 = 0;
int value5 = 0;
int result = 0;
if (Int32.TryParse(textBox11.Text, out value1) && Int32.TryParse(textBox10.Text, out value2) && Int32.TryParse(textBox9.Text, out value3) & Int32.TryParse(textBox8.Text, out value4) && Int32.TryParse(textBox15.Text, out value5))
{
result = value1 + value2 + value3 + value4 + value5;
textBox22.Text = result.ToString();
}
}
private void button3_Click(object sender, EventArgs e)
{
int value1 = 0;
int value2 = 0;
int value3 = 0;
int value4 = 0;
int value5 = 0;
int result = 0;
if (Int32.TryParse(textBox7.Text, out value1) && Int32.TryParse(textBox5.Text, out value2) && Int32.TryParse(textBox1.Text, out value3) & Int32.TryParse(textBox3.Text, out value4) && Int32.TryParse(textBox12.Text, out value5))
{
result = value1 + value2 + value3 + value4 + value5;
textBox23.Text = result.ToString();
}
}
private void button4_Click(object sender, EventArgs e)
{
int value1 = 0;
int value2 = 0;
int value3 = 0;
int value4 = 0;
int value5 = 0;
int result = 0;
if (Int32.TryParse(textBox20.Text, out value1) && Int32.TryParse(textBox19.Text, out value2) && Int32.TryParse(textBox18.Text, out value3) & Int32.TryParse(textBox17.Text, out value4) && Int32.TryParse(textBox16.Text, out value5))
{
result = value1 + value2 + value3 + value4 + value5;
textBox24.Text = result.ToString();
}
}
private void button5_Click(object sender, EventArgs e)
There are many ways to do this, however this might help you out
Make life easier with some short hand extension methods
Extension Methods
public static class TextBoxExtensions
{
public static int GetInt(this TextBox source)
{
// if TextBox null just return 0
if (source == null)
{
return 0;
}
// if it is a valid int, return it, otherwise return 0
// not we use string, in case someone put a space at the start or end
return int.TryParse(source.Text.Trim(), out var value) ? value : 0;
}
public static bool HasValidInt(this TextBox source)
{
// if TextBox null or its not an int return false
// otherwise return true
return source != null && int.TryParse(source.Text.Trim(), out var _);
}
}
Helper function to get Max
// helper function, this does not use a loop
// get the max of all textboxes
private int GetMax(params TextBox[] args)
{
return args.Where(x => x.HasValidInt()) // remove any invalid numbers
.Select(x => x.GetInt()) // project to int
.Max(); //get the max of all
}
Your existing code
using the extension methods
private void button4_Click(object sender, EventArgs e)
{
// this is just a better way to validate your text boxes with the extension method
if (textBox1.HasValidInt() && textBox2.HasValidInt() && textBox3.HasValidInt() && textBox4.HasValidInt())
{
// get the ints from all text boxes using extension method
var result = textBox1.GetInt() + textBox2.GetInt() + textBox3.GetInt() + textBox4.GetInt();
textBox6.Text = result.ToString();
}
}
Get max Version 1
This doesn't use a loop. However, does use Linq
private void button5_Click(object sender, EventArgs e)
{
// get the max of all textboxes using the helper method
textBox6.Text = GetMax(textBox1, textBox2, textBox3, textBox4).ToString();
}
Get max Version 2
This doesn't use a loop. However, does use Math.Max
private void button6_Click(object sender, EventArgs e)
{
// this is just a better way to validate your text boxes with the extension method
if (textBox1.HasValidInt() && textBox2.HasValidInt() && textBox3.HasValidInt() && textBox4.HasValidInt())
{
// use math to get the max
var result = 0;
result = Math.Max(result, textBox1.GetInt());
result = Math.Max(result, textBox2.GetInt());
result = Math.Max(result, textBox3.GetInt());
result = Math.Max(result, textBox4.GetInt());
textBox6.Text = result.ToString();
}
}
Additional Resources
Extension Methods (C# Programming Guide)
Extension methods enable you to "add" methods to existing types
without creating a new derived type, recompiling, or otherwise
modifying the original type. Extension methods are a special kind of
static method, but they are called as if they were instance methods on
the extended type. For client code written in C#, F# and Visual Basic,
there is no apparent difference between calling an extension method
and the methods that are actually defined in a type.
Getting Started with LINQ in C#
This section contains basic background information that will help you
understand the rest of the LINQ documentation and samples.
Int32.TryParse Method
Converts the string representation of a number to its 32-bit signed
integer equivalent. A return value indicates whether the operation
succeeded.
params (C# Reference)
By using the params keyword, you can specify a method parameter that
takes a variable number of arguments.
You can send a comma-separated list of arguments of the type specified
in the parameter declaration or an array of arguments of the specified
type. You also can send no arguments. If you send no arguments, the
length of the params list is zero.
Enumerable.Where Method (IEnumerable, Func)
Filters a sequence of values based on a predicate.
Enumerable.Select Method (IEnumerable, Func)
Projects each element of a sequence into a new form.
Enumerable.Max Method
Returns the maximum value in a sequence of values.
Math.Max Method
Returns the larger of two specified numbers.
Comment from IFebles
It also can be done with this (segmentating the TextBoxs within
panels):
var values = panel1.Controls.Cast<Control>()
.Where(obj => obj is TextBox)
.Select(obj => int.Parse(obj.Text))
.Max();
knowing that it can throw a FormatException if any input can't be parsed. Not as neat as the given answer, but also good to know.
I am writing a program using GUI in C# that includes three text boxes (one for name input, one for grade input and one for grade output), and five buttons (one to take in the name/grade and add to corresponding arrays, one to display just the name and grade that were just entered, one to display lowest grade, one to display highest grade and one to display the class average).
I have the form designed but need help with some of the code, there are two arrays one for the grade and one for name both which have five values initially stored within them. Here is the code I have so far:
namespace WindowsFormsApplication3
{
using static System.Console;
public partial class highestGrade : Form
{
int[] grade = new int[] { 90, 80, 60, 70, 80, };
string[] name = new string[] { "Sally", "Joe", "Sue", "Pete", "Tom", };
double sum = 0;
double average;
int x = 4;
int y = 4;
int z = 0;
public highestGrade()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
}
private void label2_Click(object sender, EventArgs e)
{
}
private void addStudent_Click(object sender, EventArgs e)
{
if (x <= 9)
{
Array.Sort(grade, name);
name[x] = textBox1.Text;
grade[x] = Convert.ToInt32(textBox2.Text);
sum = sum + grade[x];
textBox1.Text = string.Empty;
textBox2.Text = string.Empty;
}
}
private void display_Click(object sender, EventArgs e)
{
outputText.Visible = true;
outputText.Text = textBox1.Text + " " + textBox2.Text;
}
private void lowestGrade_Click(object sender, EventArgs e)
{
Array.Sort(grade, name);
outputText.Visible = true;
outputText.Text = name[z] + " " + grade[z];
}
private void button4_Click(object sender, EventArgs e)
{
Array.Sort(grade, name);
outputText.Visible = true;
outputText.Text = name[y] + " " + grade[y];
}
private void averageGrade_Click(object sender, EventArgs e)
{
for (int y = 0; y < 5; y++)
{
sum = sum + grade[y];
}
average = sum / grade.Length;
string avgOutput = Convert.ToString(average);
outputText.Visible = true;
outputText.Text = "Class Average: " + avgOutput;
y++;
}
}
}
I need the program to take input for grade/name up to 10 students, while being able to output the lowest/highest grade continually whenever the user clicks. It also needs to output the total average continuously whenever the user clicks.
The average is not calculating correctly, it keeps adding to the sum for each time the average button is clicked and I cannot get the highest grade to hold its value. For example: if i enter a new grade as 100 then click highest grade, it displays that grade which is what I want. But for the next grade if i enter 95, it replaces the 100 with the 95.
Any help would be appreciated thank you.
You have to reset the current sum before adding the grades again to calculate the average correctly:
private void averageGrade_Click(object sender, EventArgs e) {
sum = 0; // reset sum
for (int y = 0; y < 5; y++) {
sum = sum + grade[y];
}
average = sum / grade.Length;
string avgOutput = Convert.ToString(average);
outputText.Visible = true;
outputText.Text = "Class Average: " + avgOutput;
}
You can also use LINQ to calculate sums and averages, no need to write for loops:
using System.Linq;
var sum = grade.Sum();
var average = grade.Average();
As for the problem with lowest/highest grade: calculate these every time the button is clicked. Eliminate the global variables y, z.
private void lowestGrade_Click(object sender, EventArgs e) {
// this probably only needs to be sorted if a value is added or removed (addStudent_Click)
Array.Sort(grade, name);
outputText.Visible = true;
// first element (with index 0) will be the lowest because arrays are sorted now
outputText.Text = name[0] + " " + grade[0];
}
You can also use LINQ .First() and .Last() to access the first or last element of a collection or without the need of sorting use LINQ .Min() and .Max() methods.
I'm reading a file that is looking like that with a lot of strings
PrId Name Quantity Price Date
3 Milk 2 100 23-08-15
I have a button - btnDat_Click. When i click it retrieves all the dates in a listbox named listDate. I create a button named btnDataToTb_Click, i need to select the date and when i click the button it gonna show properties(Id, Name,Quantity) of all products of that date.
PrId Name Quantity Price
3 Milk 2 100
That's the whole code
char[] cc = new char[500]; int i, nr;
string[] lines = new string[250];
public void btnRead_Click(object sender, EventArgs e)
{
string FileName = textBox1.Text;
FileStream r_stream = new FileStream(FileName, FileMode.Open, FileAccess.ReadWrite);
StreamReader reads_string_from_r_stream = new StreamReader(r_stream);
i = 0;
listBox1.Items.Clear();
listBox2.Items.Clear();
for (; ; i++)
{
textBox1.Text = reads_string_from_r_stream.ReadLine();
lines[i] = textBox1.Text;
listBox1.Items.Add(lines[i]);
listBox2.Items.Add(lines[i]);
if (reads_string_from_r_stream.EndOfStream.Equals(true)) goto nn;
}
nn:
textBox2.Text = reads_string_from_r_stream.EndOfStream.ToString();
r_stream.Close();
nr = listBox1.Items.Count;
textBox6.Text = nr.ToString();
}
private void SelectPath_Click(object sender, EventArgs e)
{
OpenFileDialog openFile1 = new OpenFileDialog();
openFile1.Filter = "Text Files|*.txt";
if (openFile1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
textBox1.Text = openFile1.FileName;
}
public void button1_Click(object sender, EventArgs e)
{
int n = Convert.ToInt16(textBox6.Text);
ListB.Items.Clear();
for (i = 0; i < n; i++)
{
ListB.Items.Add(lines[i]);
}
}
private void btnDat_Click(object sender, EventArgs e)
{
int n = Convert.ToInt16(textBox6.Text);
for (i = 0; i < n; i++)
{
if(! listDate.Items.Contains(lines[i].Split('\t')[lines[i].Split('\t').Length - 1]))
{
listDate.Items.Add(lines[i].Split('\t')[lines[i].Split('\t').Length - 1]);
}
}
listData.Items.RemoveAt(0);
}
private void btnDataToTb_Click(object sender, EventArgs e)
{
if (listData.SelectedItems.Count > 0)
{
string data = listData.SelectedItem.ToString();
string[] date = data.Split('-');
int day = Convert.ToInt32(date[0]);
int month = Convert.ToInt32(date[1]);
int year = Convert.ToInt32(date[2]);
DateTime a = new DateTime(year, month, day);
for (i = 0; i < listBox2.Items.Count; i++)
{
DateTime data2 = DateTime.Parse(lines[i].Split('\t')[lines[i].Split('\t').Length - 1]);
int result = DateTime.Compare(a, data2);
if(result == 0)
listBox3.Items.Add(string.Format("{0}\t{1}\t{2}\t{3}", lines[i].Split('\t')[0], lines[i].Split('\t')[1], lines[i].Split('\t')[2], lines[i].Split('\t')[3]));
}
}
else
{
MessageBox.Show("Select a date");
}
}
I'd say you're approaching this problem wrong. Instead of reading the data, storing them in a list box, then reading and parsing them again when you need to, which is really complicated, you should rather do this:
Create a new class (e.g. Item) that has properties for the product id, name, quantity, price, and date.
When reading the data, parse the lines immediately and create a new instance of said class for each line. Store these in a List<Item>.
When working with FileStream, StreamReader etc (anything that implements IDisposable/has a Dispose() method) you should use them in a using block (like using (StreamReader sr = …) { /* work with sr here */ }); this will automatically free the object after use.
For making data visible to the GUI, you can either use data binding, or fill the listbox by hand and get the selected item with SelectedIndex.
Use Linq for querying data. To select all items on a specific date you can use var onThisDate = itemList.Where(item => item.Date == selectedDate). Linq has many more functions for selecting, filtering and projecting data.
This button is populate which means click on this button will auto generate random numbers .
This is my code:
protected void Button1_Click(object sender, EventArgs e)
{
int rid = RandomNumber(-111, 999);
int rid1 = RandomNumber(-111, 999);
int rid2 = RandomNumber(-222, 888);
int rid3 = RandomNumber(-333, 777);
int rid4 = RandomNumber(-222, 777);
int rid5 = RandomNumber(-333, 444);
int rid6 = RandomNumber(-555, 888);
int rid7 = RandomNumber(444, 999);
int rid8 = RandomNumber(111, 222);
int rid9 = RandomNumber(222, 333);
txt1.Text = rid.ToString();
txt2.Text = rid1.ToString();
txt3.Text = rid3.ToString();
txt4.Text = rid4.ToString();
txt5.Text = rid5.ToString();
txt6.Text = rid6.ToString();
txt7.Text = rid7.ToString();
txt8.Text = rid8.ToString();
txt9.Text = rid9.ToString();
}
The second button is sort list.
How to take all the numbers and follow acceding to put back in the 9 different textbox ?
This is the coding for button sortlist:
protected void Button2_Click(object sender, EventArgs e)
{
int no1;
int no2;
int no3;
int no4;
int no5;
int no6;
int no7;
int no8;
int no9;
//int answer;
no1 = int.Parse(txt1.Text);
no2 = int.Parse(txt2.Text);
no3 = int.Parse(txt3.Text);
no4 = int.Parse(txt4.Text);
no5 = int.Parse(txt5.Text);
no6 = int.Parse(txt6.Text);
no7 = int.Parse(txt7.Text);
no8 = int.Parse(txt8.Text);
no9 = int.Parse(txt9.Text);
int[] a = new int[] {no1,no2,no3,no4,no5,no6,no7,no8,no9 };
Array.Sort(a);
foreach (var str in a)
{
MessageBox.Show(str.ToString());
}
}
I can display sort ACS in MessageBox but I can't put the number ACS into textbox
But still can't get the answer, where was wrong?
Thank you for help.
You could throw the generated numbers into a list, sort the list and assign the numbers accordingly. Thus, txt1.Text = sortedRandList[0]; and so on for the rest.
To get slightly cleaner code, you could consider also throwing all the text boxes within a list, and eventually end up doing textBoxesList[i] = sortedRandList[i];. That should clean up the code a little bit.
You can create List of ints and then sort it like this :
List<int> rids = null;
protected void Button1_Click(object sender, EventArgs e)
{
rids = new List<int>()
{
RandomNumber(-111, 999),
RandomNumber(-111, 999),
RandomNumber(-222, 888),
RandomNumber(-333, 777),
RandomNumber(-222, 777),
RandomNumber(-333, 444),
RandomNumber(-555, 888),
RandomNumber(444, 999),
RandomNumber(111, 222),
RandomNumber(222, 333)
};
DisplayValues(); // use it if you want to show your values in UI
}
protected void sortButton_Click(object sender, EventArgs e)
{
rids.Sort();
DisplayValues()
}
private void DisplayValues()
{
for (int i = 0; i < Controls.Count; i++)
{
if (Controls[i] is TextBox) if(Controls[i]).ID.Contains("txt"))
(Controls[i] as TextBox).Text = rids[Int32.Parse(Controls[i].ID.Replace("txt", "")) - 1].ToString();
}
}