-2

I have to create a function to calculate the average age of a class of 50 students, here is my code

        public class Student
        {
        public int[] age = new int[10];
        Student()
        {
            age[0] = 17;
            age[1] = 19;
            age[2] = 17;
            age[3] = 18;
            age[4] = 17;
            age[5] = 18;
            age[6] = 18;
            age[7] = 19;
            age[8] = 17;
            age[9] = 18;
        }

    }
    class Program
    {
        public void averageAge(Student student)
        {
            foreach(int i in student.age)
            {
                int avgage = (i += i) / 2;
            }
        }
        static void main (string[] args)
        {
          
        }

I got an error saying cannot assign to "i" it is a foreach iteration variable, any other way I can initialize this array for ages of students, cause I have to calculate average age of 50 students so assigning 50 different times feels a bit too redundant

I don't know what I was thinking using foreach in such a manner, I have swapped the foreach with for loop now like this:

public void averageAge(Student student)
        {
            int avgage = 0;
            for (int i =0;i<50;i++)
            {
               avgage += student.age[i];
            }
            avgage /= 50;
        }
Ali Mohsin
  • 71
  • 1
  • 8
  • 1
    you cant modify the iteration variable. Use temporary variable or for loop. – tmsbrndz Dec 05 '20 at 20:39
  • 1
    Just create a variable outside the foreach and update that var instead of "i". – bre_dev Dec 05 '20 at 20:41
  • 3
    The title of your question seems not really related to your problem. – Klaus Gütter Dec 05 '20 at 20:42
  • 1
    First, you can say `int[] age = new int[] {10, 20, ... 50};` listing out all the values to init your array. Note, you don't give the size of the array, it ends up as big as it needs to. Then initialize an int variable before your loop `var sum=0;` and within the loop, do this `sum+=i;`. Then below the loop `var average=sum/student.age.Length;`. I have no idea what you expected `int avgage = (i += i) / 2;` to do. Oh yeah, and what does this have to do with the title of your question? Also note that my code does integer division (rounding down) if you want a result like 17.8, you'll need a cast – Flydog57 Dec 05 '20 at 20:47
  • you could initiate by List and find average using linq `var list = new List { 1, 8, 3, 2 }; double result = list.Average();// result: 3.5` – coder_b Dec 05 '20 at 20:48
  • My advice would be to take a step back and rethink what you are doing here: you are currently creating a student with multiple ages?? What you probably want is a bunch of students that all have a single age, right? That is not what your code currently represents. This means that I think you started off on the wrong foot, which will likely hinder your learning progress. – Rno Dec 05 '20 at 20:51
  • @ArnovanBoven I know I'm not just being redundant here but very poor in logic, pardon me I'm just a rookie, can you suggest a better format for creating an array for ages of 50 students ? should I create 50 objects ? – Ali Mohsin Dec 05 '20 at 21:21
  • @AliMohsin If you only need to store ages and do calculation on that: no, keep the array. If you want to manage students with names and any other data; yes, use an entity class named Student and a collection of Student named Students for example (using directly `var students = List` or any specialized class using composition of a list or any other collection like exposed in https://stackoverflow.com/questions/62904227/what-does-it-mean-to-inherit-from-a-list-of-a-class-c/62904287#62904287) –  Dec 07 '20 at 08:43

2 Answers2

1

Using Linq you can write:

using System.Linq;

var student = new Student();

int averageAge = (int)student.age.Average();

https://learn.microsoft.com/dotnet/api/system.linq.enumerable.average

Else you can write this loop:

int averageAge = 0;

for ( int index = 0; index < student.age.Length; index++ )
  averageAge = ( averageAge + student.age[index] ) / 2;

Console.WriteLine(avgage);

A foreach is:

foreach ( int value in student.age )
  averageAge = ( averageAge + value ) / 2;

Thus the method can be:

public int GetAverageAge(Student student)
{
  int result = 0;
    foreach ( int value in student.age )
      result = ( result + value ) / 2;
  return result;
}

You use like that:

static void main (string[] args)
{
  var student = new Student();
  int averageAge = GetAverageAge(student);
}

Output:

Linq = 17
Loop = 17

Having the constructor public and you can put the method in the class itself:

public class Student
{
  public int[] age = new int[10];

  public int GetAverageAge()
  {
    int result = 0;
    foreach ( int value in student.age )
      averageAge = ( averageAge + value ) / 2;
    return result;
  }

  public Student()
  {
    ...
  }
}

You can also use a property:

public int AverageAge
{
  get
  {
    int result = 0;
    foreach ( int value in student.age )
      averageAge = ( averageAge + value ) / 2;
    return result;
  }
}

Or simply:

public int AverageAge => (int)age.Average();

Is each instance of the class for one student having several ages or is it a students class ?

  • it is a students class actually, many students having their ages defined in the class itself, without the need of object being created, instead just passing the object to the function which calculates the average age of the array data field (ages) – Ali Mohsin Dec 05 '20 at 21:26
  • Thus you should name the class `Students` with an `s` at the end. If the number of students can vary, you may prefer to use an `List` for ages, for example. Perhaps you can also consider using a Student class for each student and a collection of students. Thus a `Student` has an `Age`, `Name`... and the `Students` collection having a field `List` for example has the `AverageAge` property and maps all what is needed to manage the list of students. –  Dec 05 '20 at 21:27
  • now that's getting a bit too complicated, it would be better if there is one class, namely studentsAges, and that class has an array data field ages, which is the collective datafield for all the ages of the students, following the instructions of my assignment, and pass the object of the studentsAges class as a parameter to the function which calculates average age – Ali Mohsin Dec 06 '20 at 12:17
0

Not an answer, but I think this is what you are trying to achieve. It may help you in your thinking process

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        // create a classroom
        var classRoom = new ClassRoom();
        // store 10 students in classroom, aged between 18 and 30 (random)
        for (int i = 0; i < 10; i++)
        {
            classRoom.Students.Add(new Student(new Random().Next(18, 30)));
        }

        // calculate average age of students in a classroom
        // this can be done a hundred ways. Linq is probably shortest
        Console.WriteLine($"There are {classRoom.Students.Count} students with an average age of { classRoom.Students.Average(s => s.Age)}");
        Console.ReadKey();
    }

    // a student has an age
    class Student
    {
        public Student(int age)
        {
            Age = age;
        }

        public int Age { get; set; }
    }

    // a class has a number of students
    class ClassRoom
    {
        public List<Student> Students { get; } = new List<Student>();
    }
}
Rno
  • 784
  • 1
  • 6
  • 16
  • this is exactly what I was looking for – Ali Mohsin Dec 06 '20 at 12:11
  • You're welcome. Note that it has nothing to do with your original question. Not even you original code has. Hence the downvotes you got. Be really specific with your questions. – Rno Dec 07 '20 at 01:10