0

PART 1: I am to create a program that that reads a file’s contents into an array, and displays the array’s contents in a ListBox control, and calculates and displays the total of the array’s values. - DONE THAT PART

PART 2: Calculate the average, Highest, and Lowest value and display them in a Label control.

I'm new to coding so I couldn't do much, I turn to stack overflow for help

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace SalesAnalysis
{
public partial class SalesAnalysisApplication : Form
{
    public SalesAnalysisApplication()
    {
        InitializeComponent();
    }

    private void salesAnalysisButton_Click(object sender, EventArgs e)
    {
        //declaring array
        const int SIZE = 100;
        decimal[] sales = new decimal[SIZE];

        //varible to hold amount stored in array
        int count = 0;



        //declaring streamreader
        StreamReader inputFile;

        //opening the sales file
        inputFile = File.OpenText("Sales.txt");

        try
        {
            //pull contents from file into array while there is still 
             // items to pull and the array isnt full

            while (!inputFile.EndOfStream && count < sales.Length)
            {
                sales[count] = decimal.Parse(inputFile.ReadLine());
                count++;
            }
            //close the file
            inputFile.Close();

            //display contents in listbox
            for (int index = 0; index < count; index++)
            {
                salesListBox.Items.Add(sales[index]);
            }


            //Calculate the sum of all values
            for (int index = 0; index < sales.Length; index++)
            {
                totalSales += sales[index];
            }
            //display total of all values
            salesListBox.Items.Add("Total =" + totalSales);


            //Determine the average sales from the array
            for (int index = 0; index < sales.Length; index++)
            {
                //calculate the average
                averageSales = totalSales / 7;
            }


        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    private void Clear_Click(object sender, EventArgs e)
    {
        //Clear all fields
        salesListBox.Items.Clear();
        averageResultsLabel.Text = "";
        highestResultsLabel.Text = "";
        lowestResultsLabel.Text = "";
    }

    private void exitButton_Click(object sender, EventArgs e)
    {
        //close form
        this.Close();
    }
}

}

  • You simply use the extension methods for *IEnumerbale* that does all these things – TheGeneral May 22 '19 at 06:18
  • 1
    Perhaps, you can't do much, but you can always split your problem into smaller parts. For example, you're asking about three different values: start with one, i.e. average, instead. Second step: you already know how to assign a value to a label, you just need to calculate the average value of the array elements, and this question was already asked here: [how can i return the sum , average of an int array](https://stackoverflow.com/a/12949933) – default locale May 22 '19 at 06:24
  • https://stackoverflow.com/questions/19413087/c-sharp-displaying-the-max-min-and-average – TheGeneral May 22 '19 at 06:26
  • you have already calculated `totalSales` it`s only 1 line from there to the average. Do you at least know how the mathematical operation is to calculate the average? – Mong Zhu May 22 '19 at 06:38
  • as for the min and max values you could do it in the same loop where you calculate the `totalSales`. Do you have any idea how you could find the smallest number if you would step through a series one by one? I guess this is homework, so you probably also want to learn something, am I right? – Mong Zhu May 22 '19 at 06:40
  • 1
    `decimal[] sales = File.ReadLines("Sales.txt").Select(line => decimal.Parse(line)).ToArray();` - you don't have to work with streams – Dmitry Bychenko May 22 '19 at 06:43
  • @MongZhu yeah ik the basic math principles -- average = totalSales / the number of arrays, but I do not know how to implement it. – Mozz Jonas May 22 '19 at 08:24
  • @MongZhu i think i figured it out, give my code a check again – Mozz Jonas May 22 '19 at 09:28
  • almost there. "average = totalSales / the number of arrays," it should be "average = totalSales / the number of **items** in the array"! you get the amount of numbers by `sales.Length` as you have already used in your for loop – Mong Zhu May 22 '19 at 10:44
  • why do you compare always the number of the position `2` ? in `if (sales[2] > lowestsales)` you need to use your index variable to be able to run through the array: `if (sales[index] > lowestsales)` as well as in the assignment: `lowestsales = sales[index];` – Mong Zhu May 22 '19 at 10:50
  • @MongZhu for some reason the formula "average= totalsales/ sales.lenght" doesnt produce the correct solution - there are 7 items in the array total sum of the 7 items = 10960.07. but using the "average= totalsales/ sales.lenght" gives a result of 109.60 AND the subscript 2 is the lowest value in the array hence why I am using it to get "lowestSales". if i run: if (sales[index] > lowestsales) lowestsales = sales[index] ---- gives me a result of 0 for lowestSales – Mozz Jonas May 22 '19 at 16:47
  • Why do you make an array with 100 positions if you put only 7 items in there? The rest of the array will be initialized with the default value of 0.this is why the minimum is 0. Maybe you should use a `List` instead of an array – Mong Zhu May 23 '19 at 09:12
  • @MongZhu because its possible that the nnumber of items in the array increases - but that is not within the scope of this program - but i still gave it 100 for the peace of mind. Thanks for all your help! – Mozz Jonas May 23 '19 at 09:22
  • You should use a List, it is made exactly for this kind of cases where your collection can increase. It will only contain as much elements as you put into it – Mong Zhu May 23 '19 at 11:11
  • I just saw that you have `int count` to count the amount of stored items. So then you should use this variable as final condition in all your for loops. run with `i < count` and the rest should work just fine. even the line: `if (sales[index] > lowestsales) lowestsales = sales[index]` – Mong Zhu May 23 '19 at 18:53
  • 1
    @MongZhu Thanks man, good a good mark, thanks to you! – Mozz Jonas May 28 '19 at 15:00

4 Answers4

6

You can use linq to do this for example:

    var list=Enumerable.Range(0,1000);

    var average = list.Average();

    var highest = list.Max()

    var smallest= list.Min()

    var total= list.Sum()

P.S do not forget to add using System.Linq;

vsarunov
  • 1,433
  • 14
  • 26
1

The non-linq approach.

You have a sales.Length and a totalSales. Therefore, you have an averageSales.

For max & min, while you are in the for loop

for (int index = 0; index < sales.Length; index ++ 
  {
    if (sales
  }

simply assign the value based on an if statement. Something like:

if (sales[index] > highestSales) 
{
  highestSales = sales[index];
}
if (sales[index] < lowestSales)
{
  lowestSales = sales[index];
}
mcalex
  • 6,628
  • 5
  • 50
  • 80
  • I am attempting your non-linq solution, still having trouble. any way I can send u the program? – Mozz Jonas May 22 '19 at 06:37
  • @MozzJonas see if the edit helps. Have you worked out averageSales? – mcalex May 22 '19 at 06:44
  • @MozzJonas I asked you those questions in my comments for a reason. I wanted to help you to develop the algorithm on your own. Would you care to answer them? – Mong Zhu May 22 '19 at 08:06
  • @MozzJonas imagine you have 10 people standing in a row. You walk from the first until the last. How would you find the talest person? You would check the first if he is taller then `0` if so, then you would remember that person, then go to the next one and compare whether he is taller then the one from your memory. If so you would overwrite your memory with the new person and so on – Mong Zhu May 22 '19 at 08:12
0

First convert u r Decimal array to List.

List<decimal> lst = sales.OfType<decimal>().ToList(); // Convert to List.

Then Follow Linq Operations.

lst.Average(); lst.Min(); 
Shyam Vemula
  • 591
  • 2
  • 14
  • 1) why using `OfType` ? a simple `sales.ToList()` would do the same 2) where is the need to transform the array into a list? An `decimal [ ]` implements `IEnumerable` and this interface defines the methods `Average` and `Min`. So the array can call these methods on it's own – Mong Zhu May 22 '19 at 06:44
  • The OfType is redundant as all elements are known to be decimal, and the ToList is unnecessary as Min/Max/Avg are defined on IEnumerable which an array already implements. – ckuri May 22 '19 at 07:12
0

In case you prefer good old loop (and no Linq), you can try File.ReadLines and foreach:

  decimal max = 0;
  decimal min = 0;
  decimal sum = 0;
  int count = 0;      

  foreach(string line in File.ReadLines("Sales.txt")) {
    decimal value = decimal.Parse(line);

    salesListBox.Items.Add(value);

    if (count == 0 || value > max)
      max = value;

    if (count == 0 || value < min)
      min = value;

    sum += value;
    count += 1;   
  } 

  decimal average = sum / count; 

  averageResultsLabel.Text = average.ToString("f2");
  highestResultsLabel.Text = max.ToString();
  lowestResultsLabel.Text = min.ToString();

Here we don't have to create any array at all. If you insist on having array a simple Linq can help

  decimal[] sales = File
    .ReadLines("Sales.txt")
    .Select(line => decimal.Parse(line))
    .ToArray();

And foreach will be

  foreach(decimal value in sales) {
    salesListBox.Items.Add(value);
    ... 
  }      
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215