Loading user input into an array
I am learning about arrays, and I need to figure out how to enter data from a form into the array. The user enters a subtotal, then the form calculates a discount percentage and amount, and give a final total. I need to have that total loaded into the array each time. The array needs to store 5 totals. Eventually I need to create a display box that will show the last five totals. Any general guidance would be greatly appreciated. I have read and re-read this in my book so many times and just not getting it. I'm thinking I would use a foreach loop here but not sure.
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace InvoiceTotal
{
// This is the starting point for exercise 8-1 from
// "Murach's C# 2010" by Joel Murach
// (c) 2010 by Mike Murach & Associates, Inc.
// www.murach.com
public partial class frmInvoiceTotal : Form
{
public frmInvoiceTotal()
{
InitializeComponent();
}
// TODO: declare class variables for array and list here
decimal[] totals = new decimal[5];
private void btnCalculate_Click(object sender, EventArgs e)
{
totals[0] = 0.0m;
totals[1] = 0.0m;
totals[3] = 0.0m;
totals[4] = 0.0m;
try
{
if (txtSubtotal.Text == "")
{
MessageBox.Show(
"Subtotal is a required field.", "Entry Error");
}
else
{
decimal subtotal = Decimal.Parse(txtSubtotal.Text);
if (subtotal > 0 && subtotal < 10000)
{
decimal discountPercent = 0m;
if (subtotal >= 500)
discountPercent = .2m;
else if (subtotal >= 250 & subtotal < 500)
discountPercent = .15m;
else if (subtotal >= 100 & subtotal < 250)
discountPercent = .1m;
decimal discountAmount = subtotal * discountPercent;
decimal invoiceTotal = subtotal - discountAmount;
discountAmount = Math.Round(discountAmount, 2);
invoiceTotal = Math.Round(invoiceTotal, 2);
txtDiscountPercent.Text = discountPercent.ToString("p1");
txtDiscountAmount.Text = discountAmount.ToString();
txtTotal.Text = invoiceTotal.ToString();
}
else
{
MessageBox.Show(
"Subtotal must be greater than 0 and less than 10,000.",
"Entry Error");
}
}
}
catch (FormatException)
{
MessageBox.Show(
"Please enter a valid number for the Subtotal field.",
"Entry Error");
}
txtSubtotal.Focus();
}
private void btnExit_Click(object sender, EventArgs e)
{
// TODO: add code that displays dialog boxes here
this.Close();
}
}
}
Re: Loading user input into an array
Been trying some different things and I have this so far, which includes the box to display all the results loaded into the array:
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace InvoiceTotal
{
// This is the starting point for exercise 8-1 from
// "Murach's C# 2010" by Joel Murach
// (c) 2010 by Mike Murach & Associates, Inc.
// www.murach.com
public partial class frmInvoiceTotal : Form
{
public frmInvoiceTotal()
{
InitializeComponent();
}
// TODO: declare class variables for array and list here
decimal[] totals = new decimal[5];
private void btnCalculate_Click(object sender, EventArgs e)
{
totals[0] = 0.0m;
totals[1] = 0.0m;
totals[3] = 0.0m;
totals[4] = 0.0m;
try
{
if (txtSubtotal.Text == "")
{
MessageBox.Show(
"Subtotal is a required field.", "Entry Error");
}
else
{
decimal subtotal = Decimal.Parse(txtSubtotal.Text);
if (subtotal > 0 && subtotal < 10000)
{
decimal discountPercent = 0m;
if (subtotal >= 500)
discountPercent = .2m;
else if (subtotal >= 250 & subtotal < 500)
discountPercent = .15m;
else if (subtotal >= 100 & subtotal < 250)
discountPercent = .1m;
decimal discountAmount = subtotal * discountPercent;
decimal invoiceTotal = subtotal - discountAmount;
discountAmount = Math.Round(discountAmount, 2);
invoiceTotal = Math.Round(invoiceTotal, 2);
txtDiscountPercent.Text = discountPercent.ToString("p1");
txtDiscountAmount.Text = discountAmount.ToString();
txtTotal.Text = invoiceTotal.ToString();
for (int i = 0; i < totals.Length; i++)
invoiceTotal += totals[i];
}
else
{
MessageBox.Show(
"Subtotal must be greater than 0 and less than 10,000.",
"Entry Error");
}
}
}
catch (FormatException)
{
MessageBox.Show(
"Please enter a valid number for the Subtotal field.",
"Entry Error");
}
txtSubtotal.Focus();
string numbersString = "";
foreach (decimal invoiceTotal in totals)
numbersString += invoiceTotal + "\n";
MessageBox.Show(numbersString, "Totals");
}
private void btnExit_Click(object sender, EventArgs e)
{
// TODO: add code that displays dialog boxes here
this.Close();
}
}
}
However, the output is always:
0.0
0.0
0
0.0
0.0
Can anyone point me towards the problem?
Re: Loading user input into an array
This block zeros the saved totals every time the button is clicked:
Code:
totals[0] = 0.0m;
totals[1] = 0.0m;
totals[3] = 0.0m;
totals[4] = 0.0m;
(Actually, you miss totals[2]). Instead, you should put this in the public frmInvoiceTotal() subroutine, after InitializeComponents, so that this initialization happens once per form loading (not per button click). Also you can write it more compactly:
Code:
for(int i = 0; i < totals.Length; i++)
totals[i] = 0;
Actually, even that is unnecessary, since decimals are initialized to zero on creation.
But anyway, then to save the last five totals, you should do something like:
Code:
//Move all totals forward by one
for(int i = 0; i < totals.Length - 1; i++)
{
totals[i+1] = totals[i];
}
//And save the new total
totals[0] = invoiceTotal;
And then to calculate the final sum-of-last-5-totals
Code:
invoiceTotal = 0;
for(int i = 0; i < totals.Length; i++)
{
invoiceTotal += totals[i];
}
Hope that helps!
Re: Loading user input into an array
Thanks a lot BioPhysEngr, that did help a lot. The only problem I am running into now is that the message box shows the last entered total in the first spot and whatever the last total was in the remaining 4 spots, like this:
$1600.00
$800.00
$800.00
$800.00
$800.00
This is after entering in 5 different subtotals. Trying to work this problem out, here's the code I have so far...
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace InvoiceTotal
{
// This is the starting point for exercise 8-1 from
// "Murach's C# 2010" by Joel Murach
// (c) 2010 by Mike Murach & Associates, Inc.
// www.murach.com
public partial class frmInvoiceTotal : Form
{
public frmInvoiceTotal()
{
InitializeComponent();
totals[0] = 0.0m;
totals[1] = 0.0m;
totals[2] = 0.0m;
totals[3] = 0.0m;
totals[4] = 0.0m;
}
// TODO: declare class variables for array and list here
decimal[] totals = new decimal[5];
private void btnCalculate_Click(object sender, EventArgs e)
{
try
{
if (txtSubtotal.Text == "")
{
MessageBox.Show(
"Subtotal is a required field.", "Entry Error");
}
else
{
decimal subtotal = Decimal.Parse(txtSubtotal.Text);
if (subtotal > 0 && subtotal < 10000)
{
decimal discountPercent = 0m;
if (subtotal >= 500)
discountPercent = .2m;
else if (subtotal >= 250 & subtotal < 500)
discountPercent = .15m;
else if (subtotal >= 100 & subtotal < 250)
discountPercent = .1m;
decimal discountAmount = subtotal * discountPercent;
decimal invoiceTotal = subtotal - discountAmount;
discountAmount = Math.Round(discountAmount, 2);
invoiceTotal = Math.Round(invoiceTotal, 2);
txtDiscountPercent.Text = discountPercent.ToString("p1");
txtDiscountAmount.Text = discountAmount.ToString("c");
txtTotal.Text = invoiceTotal.ToString("c");
for (int i = 0; i < totals.Length - 1; i++)
{
totals[i + 1] = totals[i];
}
totals[0] = invoiceTotal;
}
else
{
MessageBox.Show(
"Subtotal must be greater than 0 and less than 10,000.",
"Entry Error");
}
}
}
catch (FormatException)
{
MessageBox.Show(
"Please enter a valid number for the Subtotal field.",
"Entry Error");
}
txtSubtotal.Focus();
}
private void btnExit_Click(object sender, EventArgs e)
{
// TODO: add code that displays dialog boxes here
string totalsString = "";
foreach (decimal invoiceTotal in totals)
totalsString += invoiceTotal + "\n";
MessageBox.Show(totalsString, "Totals");
this.Close();
}
}
}
Re: Loading user input into an array
Ah! Quite right. That's a bug in the code I suggested. You have to run the loop backward:
Code:
for (int i = totals.Length -1; i > 0; i--)
{
totals[i] = totals[i-1];
}
totals[0] = invoiceTotal;
Re: Loading user input into an array
Thanks again BioPhysEngr, I was able to get it to load correctly now. In addition, I added a sort so it shows the totals in ascending order. I was also required to duplicate the array as a list and have it display a second message box showing the totals. I think I have it working correctly now. If anyone wants to look over my code I'd appreciate any feedback. Thanks again for all your help!
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace InvoiceTotal
{
// This is the starting point for exercise 8-1 from
// "Murach's C# 2010" by Joel Murach
// (c) 2010 by Mike Murach & Associates, Inc.
// www.murach.com
public partial class frmInvoiceTotal : Form
{
public frmInvoiceTotal()
{
InitializeComponent();
totals[0] = 0.0m;
totals[1] = 0.0m;
totals[2] = 0.0m;
totals[3] = 0.0m;
totals[4] = 0.0m;
}
// TODO: declare class variables for array and list here
decimal[] totals = new decimal[5];
List<decimal> totalsList = new List<decimal>();
private void btnCalculate_Click(object sender, EventArgs e)
{
try
{
if (txtSubtotal.Text == "")
{
MessageBox.Show(
"Subtotal is a required field.", "Entry Error");
}
else
{
decimal subtotal = Decimal.Parse(txtSubtotal.Text);
if (subtotal > 0 && subtotal < 10000)
{
decimal discountPercent = 0m;
if (subtotal >= 500)
discountPercent = .2m;
else if (subtotal >= 250 & subtotal < 500)
discountPercent = .15m;
else if (subtotal >= 100 & subtotal < 250)
discountPercent = .1m;
decimal discountAmount = subtotal * discountPercent;
decimal invoiceTotal = subtotal - discountAmount;
discountAmount = Math.Round(discountAmount, 2);
invoiceTotal = Math.Round(invoiceTotal, 2);
txtDiscountPercent.Text = discountPercent.ToString("p1");
txtDiscountAmount.Text = discountAmount.ToString("c");
txtTotal.Text = invoiceTotal.ToString("c");
for (int i = totals.Length - 1; i > 0; i--)
{
totals[i] = totals[i - 1];
}
for (int i = totalsList.Count - 1; i > 0; i--)
{
totalsList[1] = totalsList[i - 1];
}
totals[0] = invoiceTotal;
}
else
{
MessageBox.Show(
"Subtotal must be greater than 0 and less than 10,000.",
"Entry Error");
}
}
}
catch (FormatException)
{
MessageBox.Show(
"Please enter a valid number for the Subtotal field.",
"Entry Error");
}
txtSubtotal.Focus();
}
private void btnExit_Click(object sender, EventArgs e)
{
// TODO: add code that displays dialog boxes here
Array.Sort(totals);
string totalsString = "";
foreach (decimal invoiceTotal in totals)
if (invoiceTotal != 0)
totalsString += invoiceTotal + "\n";
MessageBox.Show(totalsString, "Totals");
foreach (decimal invoiceTotal in totalsList)
if (invoiceTotal != 0)
totalsString += invoiceTotal + "\n";
MessageBox.Show(totalsString, "Totals List");
this.Close();
}
}
}