0% found this document useful (0 votes)
8 views26 pages

Code Final

The document defines a class library for managing student data, including classes for students, their average scores, and groups based on first names and grades. It includes methods for analyzing this data, such as identifying students with average scores below 75, grouping students by first names, and finding students with the same grades in subjects. The code also includes a sample program demonstrating the usage of these classes and methods.

Uploaded by

mja.aranzado29
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views26 pages

Code Final

The document defines a class library for managing student data, including classes for students, their average scores, and groups based on first names and grades. It includes methods for analyzing this data, such as identifying students with average scores below 75, grouping students by first names, and finding students with the same grades in subjects. The code also includes a sample program demonstrating the usage of these classes and methods.

Uploaded by

mja.aranzado29
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 26

Code

CLASS LIBRARY
namespace ClassLibrary1
{
public class Student
{
public int StudentID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<int> Scores { get; set; }
}

public class StudentWithAverage


{
public string FullName { get; set; }
public double AverageScore { get; set; }
}

public class FirstNameGroup


{
public string FirstName { get; set; }
public List<string> Students { get; set; }
}

public class GradeGroup


{
public int SubjectIndex { get; set; }
public int Grade { get; set; }
public List<string> FullNames { get; set; }
}
public static class StudentAnalyzer
{
public static List<StudentWithAverage> GetStudentsWithAverageBelow75(List<Student>
students)
{
return students
.Where(s => s.Scores.Average() < 75)
.Select(s => new StudentWithAverage
{
FullName = $"{s.FirstName} {s.LastName}",
AverageScore = s.Scores.Average()
})
.ToList();
}

public static List<FirstNameGroup> GetStudentsWithSameFirstName(List<Student>


students)
{
return students
.GroupBy(s => s.FirstName)
.Where(g => g.Count() > 1)
.Select(g => new FirstNameGroup
{
FirstName = g.Key,
Students = g.Select(s => $"{s.FirstName} {s.LastName}").ToList()
})
.ToList();
}

public static List<GradeGroup> GetSameGradeGroups(List<Student> students)


{
return Enumerable.Range(0, 4)
.SelectMany(subjectIndex =>
students
.GroupBy(s => s.Scores[subjectIndex])
.Where(g => g.Count() > 1)
.Select(g => new GradeGroup
{
SubjectIndex = subjectIndex,
Grade = g.Key,
FullNames = g.Select(s => $"{s.FirstName} {s.LastName}").ToList()
}))
.ToList();
}
}
}

Code with comments:

CLASS LIBRARY
namespace ClassLibrary1
{
// Define a class that represents a student with ID, FirstName, LastName, and scores
public class Student
{
public int StudentID { get; set; } // Property to store unique identifier for each student
public string FirstName { get; set; } // Property to store student’s first name
public string LastName { get; set; } // Property to store student’s last name
public List<int> Scores { get; set; } // Property to store a list of student’s subject score
}
// Defines a class that represent students with their full name and average score
public class StudentWithAverage
{
public string FullName { get; set; } //Concatenation of the student’s first and last
name
public double AverageScore { get; set; } //Calculated average score
}
// Defines a class to group the students who share the same first name
public class FirstNameGroup
{
public string FirstName { get; set; } //Property to store the same first name
public List<string> Students { get; set; } // Property to store the list of student’s full
name
}
//Defines a class to group student who have the same grade in a particular subject
public class GradeGroup
{
public int SubjectIndex { get; set; } // Property to store the index of the subject
public int Grade { get; set; } // Property to store the grade of the subject
public List<string> FullNames { get; set; } // List of student’s full name with the grade
on the subject
}
// A static class that contains an analysis method for students
public static class StudentAnalyzer
{
// Finds students with an average score below 75
public static List<StudentWithAverage> GetStudentsWithAverageBelow75(List<Student>
students)
{

return students
.Where(s => s.Scores.Average() < 75) // Filter students with an average score <
75
.Select(s => new StudentWithAverage // Project each student into
StudentWithAverage object
{
FullName = $"{s.FirstName} {s.LastName}", // Concatenate first and last
name for full name
AverageScore = s.Scores.Average() // Calculate the student’s average
score
})
.ToList(); // Convert the result to a list
}

// Find a group of students that shares the same first name


public static List<FirstNameGroup> GetStudentsWithSameFirstName(List<Student>
students)
{
return students
.GroupBy(s => s.FirstName) // Group students by their FirstName
.Where(g => g.Count() > 1) // Filter groups that have more that one
student
.Select(g => new FirstNameGroup // Project each group into a FirstNameGroup
object
{
// Set the first name of the group
FirstName = g.Key,
// List of full names of all students in this group
Students = g.Select(s => $"{s.FirstName} {s.LastName}").ToList()
})
.ToList(); // Convert the result to a list
}

// Find group of students who have the same grade in each subject
public static List<GradeGroup> GetSameGradeGroups(List<Student> students)
{
return Enumerable.Range(0, 4) //Loop through subjects (0-3)
.SelectMany(subjectIndex => // For each subject index, group students by their
score
students
.GroupBy(s => s.Scores[subjectIndex]) // Group students by their score in the
current subject
.Where(g => g.Count() > 1) // Filter groups that have more than
one student
.Select(g => new GradeGroup // Projefct each group into a
GradeGroup object
{
SubjectIndex = subjectIndex, // Set the subject index
Grade = g.Key, // Set the grade for this group
// List of full name of students with this grade
FullNames = g.Select(s => $"{s.FirstName} {s.LastName}").ToList()
}))
.ToList(); // Convert the result to a list
}
}
}

Explanation of each function

1. `GetStudentsWithAverageBelow75`

Purpose:

This function identifies students whose average scores across all subjects are less than 75. It returns a
list of `StudentWithAverage` objects, each containing the student's full name and their average score.

How it works:

- It takes a list of `Student` objects as input.

- Uses LINQ `Where` to filter students where the average of their scores is less than 75.

- Projects each filtered student into a new `StudentWithAverage` object:

- `FullName`: Concatenates first and last names.

- `AverageScore`: Calculates the average of the scores.

- Converts the resulting sequence into a list.

2. `GetStudentsWithSameFirstName`

Purpose:

This function finds all students who share the same first name with at least one other student. It groups
such students by their first name into `FirstNameGroup` objects.

How it works:

- Groups the list of students by their `FirstName` using `GroupBy`.

- Filters groups where the count of students is greater than 1 (meaning multiple students share that first
name).

- Projects each group into a `FirstNameGroup`:

- `FirstName`: The shared first name.

- `Students`: A list of full names (`FirstName LastName`) of all students in that group.

- Returns a list of these groups.


3. `GetSameGradeGroups`

Purpose:

This function finds groups of students who share the same grade (score) in each subject. It examines
each subject separately and groups students who have the same score in that subject.

How it works:

- Assumes each student has scores for 4 subjects (indices 0 to 3).

- Creates a sequence of subject indices (0, 1, 2, 3) using `Enumerable.Range`.

- For each subject index:

- Groups students by their score in that subject.

- Filters groups with more than one student (i.e., multiple students with the same grade).

- Projects each group into a `GradeGroup`:

- `SubjectIndex`: The current subject.

- `Grade`: The shared score.

- `FullNames`: List of students' full names with that score.

- Uses `SelectMany` to flatten all these groups across all subjects into a single list.

Summary
The provided code defines a class library that models student data and provides functionalities to
analyze this data. It consists of several classes and a static class with methods for data analysis.

1. Namespace Declaration

namespace ClassLibrary1

- This line declares a namespace called `ClassLibrary1`. Namespaces are used to organize code and
prevent naming conflicts. All classes and methods defined within this block belong to this namespace.

2. Data Model Classes

The code defines four classes that represent different aspects of student data:

- Student Class

public class Student

{
public int StudentID { get; set; }

public string FirstName { get; set; }

public string LastName { get; set; }

public List<int> Scores { get; set; }

Purpose: Represents a student with properties for their ID, first name, last name, and a list of scores.

Properties:

- `StudentID`: An integer representing the unique identifier for the student.

- `FirstName`: A string representing the student's first name.

- `LastName`: A string representing the student's last name.

- `Scores`: A list of integers representing the scores the student has received in various subjects.

StudentWithAverage Class

public class StudentWithAverage

public string FullName { get; set; }

public double AverageScore { get; set; }

Purpose: Represents a student along with their average score.

Properties:

- `FullName`: A string that combines the student's first and last names.

- `AverageScore`: A double representing the average score of the student.

FirstNameGroup Class

public class FirstNameGroup

public string FirstName { get; set; }

public List<string> Students { get; set; }

}
Purpose: Represents a group of students who share the same first name.

Properties:

- `FirstName`: A string representing the common first name.

- `Students`: A list of strings containing the full names of students with that first name.

GradeGroup Class

public class GradeGroup

public int SubjectIndex { get; set; }

public int Grade { get; set; }

public List<string> FullNames { get; set; }

Purpose: Represents a group of students who received the same grade in a specific subject.

Properties:

- `SubjectIndex`: An integer representing the index of the subject.

- `Grade`: An integer representing the grade received by the students in that subject.

- `FullNames`: A list of strings containing the full names of students who received that grade.

3. StudentAnalyzer Static Class

public static class StudentAnalyzer

- This static class contains methods for analyzing student data. Being static means that it cannot be
instantiated, and its methods can be called directly on the class itself.

Analysis Methods

GetStudentsWithAverageBelow75

Functionality: Identifies students with an average score below 75 and returns their full names and
average scores.
GetStudentsWithSameFirstName

Functionality: Groups students by their first names and returns groups that contain more than one
student with the same first name.

GetSameGradeGroups

Functionality: Groups students by their grades in different subjects and returns groups that contain
more than one student with the same grade.

Summary of the Code's Purpose

The overall purpose of this code is to provide a structured way to represent student data and perform
analyses on that data. The classes serve as data models, while the methods in the `StudentAnalyzer`
class allow for various analyses, such as:

- Finding students who are struggling academically (average score below 75).

- Identifying students with the same first name, which can be useful for social or administrative
purposes.

- Grouping students by their performance in specific subjects, which can help educators understand
trends in grades.

PROGRAM.cs
using System;
using System.Collections.Generic;
using System.Linq;
using ClassLibrary1;
using static ClassLibrary1.GradeGroup;

public class Program


{
static void Main()
{
List<Student> students = new List<Student>
{
new Student { StudentID = 101, FirstName = "Alice", LastName = "Smith", Scores = new
List<int> { 85, 92, 78, 95 }},
new Student { StudentID = 102, FirstName = "Bob", LastName = "Johnson", Scores =
new List<int> { 76, 88, 90, 70 }},
new Student { StudentID = 103, FirstName = "Charlie", LastName = "Brown", Scores =
new List<int> { 92, 95, 90, 98 }},
new Student { StudentID = 104, FirstName = "David", LastName = "Lee", Scores = new
List<int> { 68, 75, 80, 70 }},
new Student { StudentID = 105, FirstName = "Eve", LastName = "Davis", Scores = new
List<int> { 95, 75, 92, 97 }}
};

var newstudents = new List<Student>


{
new Student { StudentID = 106, FirstName = "Amy", LastName = "Clark", Scores = new
List<int> { 90, 85, 88, 91 } },
new Student { StudentID = 107, FirstName = "Ivy", LastName = "Wright", Scores = new
List<int> { 76, 81, 74, 80 } },
new Student { StudentID = 108, FirstName = "Cathy", LastName = "Moore", Scores =
new List<int> { 95, 97, 96, 98 } },
new Student { StudentID = 109, FirstName = "Dan", LastName = "Hall", Scores = new
List<int> { 64, 60, 62, 58 } },
new Student { StudentID = 110, FirstName = "Ella", LastName = "Green", Scores = new
List<int> { 85, 86, 89, 90 } },
new Student { StudentID = 111, FirstName = "Frank", LastName = "Young", Scores =
new List<int> { 70, 72, 68, 75 } },
new Student { StudentID = 112, FirstName = "Grace", LastName = "Baker", Scores =
new List<int> { 91, 93, 92, 90 } },
new Student { StudentID = 113, FirstName = "Hank", LastName = "Walker", Scores =
new List<int> { 55, 60, 58, 59 } },
new Student { StudentID = 114, FirstName = "Ivy", LastName = "Scott", Scores = new
List<int> { 78, 82, 79, 81 } },
new Student { StudentID = 115, FirstName = "Jack", LastName = "Adams", Scores = new
List<int> { 88, 85, 87, 89 } }
};

students.AddRange(newstudents);

var avgBelow75 = StudentAnalyzer.GetStudentsWithAverageBelow75(students);

Console.WriteLine("Students with average below 75:");


foreach (var student in avgBelow75)
{
Console.WriteLine($"- {student.FullName} = {student.AverageScore:F2}");
}

var firstNameGroups = StudentAnalyzer.GetStudentsWithSameFirstName(students);

Console.WriteLine("\nStudents with the same first name:");


foreach (var group in firstNameGroups)
{
Console.WriteLine($"{group.FirstName}: {string.Join(", ", group.Students.Select(name =>
$"\"{name}\""))}");
}

var sameGradeGroups = StudentAnalyzer.GetSameGradeGroups(students);

foreach (var group in sameGradeGroups.GroupBy(g => g.SubjectIndex))


{
Console.WriteLine($"\nGrouped by same grade in Subject {group.Key + 1}:");
foreach (var g in group)
{
Console.WriteLine($"Grade {g.Grade}: {string.Join(", ", g.FullNames.Select(name =>
$"\"{name}\""))}");
}
}
}
}

Code with comments

using System; // Provides basic functionality, including console input/output


using System.Collections.Generic; // Provides generic collection classes, such as List<T>
using System.Linq; // Provides LINQ functionality for querying collections
using ClassLibrary1; // Imports the ClassLibrary1 namespace, which contains the Student and
StudentAnalyzer classes
using static ClassLibrary1.GradeGroup; // Allows direct access to members of the GradeGroup class
without needing to qualify them
public class Program // Define the main program class

static void Main() // Main method: Entry point of the program

List<Student> students = new List<Student> // Create a list of students with their details

new Student { StudentID = 101, FirstName = "Alice", LastName = "Smith", Scores = new List<int>
{ 85, 92, 78, 95 }},

new Student { StudentID = 102, FirstName = "Bob", LastName = "Johnson", Scores = new List<int>
{ 76, 88, 90, 70 }},

new Student { StudentID = 103, FirstName = "Charlie", LastName = "Brown", Scores = new
List<int> { 92, 95, 90, 98 }},

new Student { StudentID = 104, FirstName = "David", LastName = "Lee", Scores = new List<int>
{ 68, 75, 80, 70 }},

new Student { StudentID = 105, FirstName = "Eve", LastName = "Davis", Scores = new List<int>
{ 95, 75, 92, 97 }}

};

var newstudents = new List<Student> // Create another list of new students

// Adding individual Student objects to the new list

new Student { StudentID = 106, FirstName = "Amy", LastName = "Clark", Scores = new List<int>
{ 90, 85, 88, 91 } },

new Student { StudentID = 107, FirstName = "Ivy", LastName = "Wright", Scores = new List<int>
{ 76, 81, 74, 80 } },

new Student { StudentID = 108, FirstName = "Cathy", LastName = "Moore", Scores = new List<int>
{ 95, 97, 96, 98 } },

new Student { StudentID = 109, FirstName = "Dan", LastName = "Hall", Scores = new List<int>
{ 64, 60, 62, 58 } },
new Student { StudentID = 110, FirstName = "Ella", LastName = "Green", Scores = new List<int>
{ 85, 86, 89, 90 } },

new Student { StudentID = 111, FirstName = "Frank", LastName = "Young", Scores = new List<int>
{ 70, 72, 68, 75 } },

new Student { StudentID = 112, FirstName = "Grace", LastName = "Baker", Scores = new List<int>
{ 91, 93, 92, 90 } },

new Student { StudentID = 113, FirstName = "Hank", LastName = "Walker", Scores = new List<int>
{ 55, 60, 58, 59 } },

new Student { StudentID = 114, FirstName = "Ivy", LastName = "Scott", Scores = new List<int>
{ 78, 82, 79, 81 } },

new Student { StudentID = 115, FirstName = "Jack", LastName = "Adams", Scores = new List<int> {
88, 85, 87, 89 } }

};

students.AddRange(newstudents); // Add the new students to the existing list of students

var avgBelow75 = StudentAnalyzer.GetStudentsWithAverageBelow75(students); // Call the method


to get students with an average score below 75

Console.WriteLine("Students with average below 75:"); // Output the results for students with
average scores below 75

foreach (var student in avgBelow75) // Loop through each student in he result

// Print each student's full name and average score formatted to two decimal places

Console.WriteLine($"- {student.FullName} = {student.AverageScore:F2}");

// Call the method to get groups of students with the same first name

var firstNameGroups = StudentAnalyzer.GetStudentsWithSameFirstName(students);

Console.WriteLine("\nStudents with the same first name:"); // Output the results for students with
the same first name

foreach (var group in firstNameGroups) // Loop through each group


{

Console.WriteLine($"{group.FirstName}: {string.Join(", ", group.Students.Select(name =>


$"\"{name}\""))}"); // Print the shared first name Then join and display all full names in that group, each
enclosed in quotes

var sameGradeGroups = StudentAnalyzer.GetSameGradeGroups(students); // Call method to get


groups of students with the same grade in each subject

foreach (var group in sameGradeGroups.GroupBy(g => g.SubjectIndex)) // Group these grade


groups by the subject index (which subject they pertain to)

Console.WriteLine($"\nGrouped by same grade in Subject {group.Key + 1}:"); // Print a header


indicating which subject's grade groups are being displayed

foreach (var g in group) // Loop through each grade group for this subject

Console.WriteLine($"Grade {g.Grade}: {string.Join(", ", g.FullNames.Select(name =>


$"\"{name}\""))}"); // Print the grade value and the list of students with that grade

Explanation of each function

1. `Main` Method

Purpose: This is the entry point of the program where execution begins. It orchestrates the creation of
student data, calls analysis methods, and outputs results to the console.

2. Creating the Initial List of Students


Purpose: Initializes a list of `Student` objects with predefined data, including student IDs, names, and
scores.
Functionality: Each `Student` object is created with specific properties, and these objects are added to
the `students` list.

3. Creating a New List of Students

Purpose: Initializes another list of `Student` objects with additional data.


Functionality: Similar to the previous list, this creates new `Student` objects and adds them to the
`newstudents` list.

4. Combining the Two Lists

students.AddRange(newstudents);

Purpose: Combines the `newstudents` list into the existing `students` list.
Functionality: The `AddRange` method appends all elements from `newstudents` to `students`, resulting
in a single list containing all student data.

5. Analyzing Students with Average Scores Below 75

var avgBelow75 = StudentAnalyzer.GetStudentsWithAverageBelow75(students);

Purpose: Calls the `GetStudentsWithAverageBelow75` method from the `StudentAnalyzer

Summary

Purpose of the program

 Identifies students whose average score is below 75.


 Groups students who share the same first name.
 Groups students who received the same score in the same subject.

It uses a helper class library (`ClassLibrary1`) that defines models and analysis methods for students.
Core Components Used

Student: A class representing each student with ID, name, and a list of scores.

StudentAnalyzer: A static class that contains methods to analyze student data.

Step-by-Step Breakdown

1. Import Namespaces**

using System;
using System.Collections.Generic;
using System.Linq;
using ClassLibrary1;
using static ClassLibrary1.GradeGroup;

- Brings in necessary system and custom namespaces for collection, LINQ, and the class library.

2. Main Method Begins

public class Program


{
static void Main()
{

This is the entry point of the program where execution begins.

3. Create Initial List of Students

List<Student> students = new List<Student>


{
new Student { StudentID = 101, FirstName = "Alice", LastName = "Smith", Scores = new List<int> { 85,
92, 78, 95 }},
...
};

A list of 5 `Student` objects is initialized, each with:

* An ID,
* First and last name,
* A list of 4 integer scores (assumed to be scores in 4 subjects).
4. Add More Students

var newstudents = new List<Student>


{
new Student { StudentID = 106, FirstName = "Amy", LastName = "Clark", Scores = new List<int> { 90,
85, 88, 91 } },
...
};

Creates 10 more `Student` objects with similar structure.

5. Combine Both Lists

students.AddRange(newstudents);

- Appends the `newstudents` list to the original `students` list.


- Now `students` contains 15 students.

6. Analyze Students with Low Averages

var avgBelow75 = StudentAnalyzer.GetStudentsWithAverageBelow75(students);

- Calls a method from the `StudentAnalyzer` class.


- It filters students whose **average score across 4 subjects is below 75**.

Print Results:

Console.WriteLine("Students with average below 75:");


foreach (var student in avgBelow75)
{
Console.WriteLine($"- {student.FullName} = {student.AverageScore:F2}");
}
```

- Displays the full name and average score (formatted to 2 decimal places) of each student found above.

7. Analyze Students with Same First Name

var firstNameGroups = StudentAnalyzer.GetStudentsWithSameFirstName(students);


```

- Finds students who share the same first name (e.g., two students named "Ivy").

Print Results:
Console.WriteLine("\nStudents with the same first name:");
foreach (var group in firstNameGroups)
{
Console.WriteLine($"{group.FirstName}: {string.Join(", ", group.Students.Select(name =>
$"\"{name}\""))}");
}
```

* For each group of duplicate first names:

* Displays the first name,


* Lists all students (with full names) who have that first name.

8. Group Students with Same Score in Same Subject

var sameGradeGroups = StudentAnalyzer.GetSameGradeGroups(students);


```

- Analyzes students to find those who received the exact same grade in a specific subject

Print Results:

foreach (var group in sameGradeGroups.GroupBy(g => g.SubjectIndex))


{
Console.WriteLine($"\nGrouped by same grade in Subject {group.Key + 1}:");
foreach (var g in group)
{
Console.WriteLine($"Grade {g.Grade}: {string.Join(", ", g.FullNames.Select(name =>
$"\"{name}\""))}");
}
}
```

* Groups results by subject index (0–3) representing Subject 1 to Subject 4.


* Prints which students received the same grade in that subject.

What You Get in the Console

Example of output:

```
Students with average below 75:
- David Lee = 73.25
- Dan Hall = 61.00
- Hank Walker = 58.00

Students with the same first name:


Ivy: "Ivy Wright", "Ivy Scott"

Grouped by same grade in Subject 1:


Grade 76: "Bob Johnson", "Ivy Wright"
...

Summary of the Whole Code

* The program defines a set of student records.


* It uses helper analysis methods to:

1. Find underperformers.
2. Detect naming duplicates.
3. Group similar subject grades.
- It outputs all these insights in an organized way.

UNIT TEST
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Linq;
using ClassLibrary1;

namespace UnitTesting
{
[TestClass]
public class StudentAnalyzerTests
{
private List<Student> getSampleStudents()
{
return new List<Student>
{
new Student { FirstName = "Alice", LastName = "Smith", Scores = new List<int> { 85,
92, 78, 95 } },
new Student { FirstName = "Bob", LastName = "Johnson", Scores = new List<int>
{ 50, 60, 65, 70 } },
new Student { FirstName = "Alice", LastName = "Jones", Scores = new List<int> { 88,
90, 85, 87 } },
new Student { FirstName = "Charlie", LastName = "Brown", Scores = new List<int>
{ 92, 95, 90, 98 } },
new Student { FirstName = "Dan", LastName = "Hall", Scores = new List<int> { 64,
60, 62, 58 } }
};
}

[TestMethod]
public void studentsWithAverageBelow75_ShouldReturnCorrectNamesAndGrades()
{
var students = getSampleStudents();
var result = StudentAnalyzer.GetStudentsWithAverageBelow75(students);

var fullNames = result.Select(r => r.FullName).ToList();

CollectionAssert.Contains(fullNames, "Bob Johnson");


CollectionAssert.Contains(fullNames, "Dan Hall");
CollectionAssert.DoesNotContain(fullNames, "Alice Smith");

// Optional: check their actual averages


var bob = result.FirstOrDefault(r => r.FullName == "Bob Johnson");
var dan = result.FirstOrDefault(r => r.FullName == "Dan Hall");
Assert.IsTrue(bob.AverageScore < 75);
Assert.IsTrue(dan.AverageScore < 75);
}

[TestMethod]
public void studentsWithSameFirstName_ShouldReturnAliceGroup()
{
var students = getSampleStudents();
var result = StudentAnalyzer.GetStudentsWithSameFirstName(students);

var aliceGroup = result.FirstOrDefault(g => g.FirstName == "Alice");


Assert.IsNotNull(aliceGroup);
Assert.AreEqual(2, aliceGroup.Students.Count);
CollectionAssert.Contains(aliceGroup.Students, "Alice Smith");
CollectionAssert.Contains(aliceGroup.Students, "Alice Jones");
}

[TestMethod]
public void sameGradeGroups_ShouldIncludeCommonGrade()
{
var students = getSampleStudents();
var result = StudentAnalyzer.GetSameGradeGroups(students);

var match = result.FirstOrDefault(g => g.Grade == 60 && g.SubjectIndex == 1);


Assert.IsNotNull(match);
CollectionAssert.Contains(match.FullNames, "Bob Johnson");
CollectionAssert.Contains(match.FullNames, "Dan Hall");
}
}
}

Code with comments

using Microsoft.VisualStudio.TestTools.UnitTesting; // Required for writing unit tests using MSTest


framework
using System.Collections.Generic; // For using lists and LINQ features
using System.Linq; // Reference to your class library that contains Student and StudentAnalyzer classes

using ClassLibrary1;

namespace UnitTesting // Defines the namespace for the test class


{
[TestClass] // Declares the class that will contain unit tests
public class StudentAnalyzerTests
{
private List<Student> getSampleStudents() // Helper method to generate a sample list of students
used in multiple tests
{
return new List<Student>
{
new Student { FirstName = "Alice", LastName = "Smith", Scores = new List<int> { 85, 92, 78, 95 }
}, // Student with high scores
new Student { FirstName = "Bob", LastName = "Johnson", Scores = new List<int> { 50, 60, 65, 70
} }, // Student with average below 75
new Student { FirstName = "Alice", LastName = "Jones", Scores = new List<int> { 88, 90, 85,
87 } }, // Another student with the same first name as above ("Alice")
new Student { FirstName = "Charlie", LastName = "Brown", Scores = new List<int> { 92, 95, 90,
98 } } // High-performing student
new Student { FirstName = "Dan", LastName = "Hall", Scores = new List<int> { 64, 60, 62, 58 } }
// Another student with average below 75
};
}

// First unit test: Checks that only students with an average score below 75 are returned
[TestMethod]
public void studentsWithAverageBelow75ShouldReturnCorrectNamesAndGrades()
{
var students = getSampleStudents(); // Get sample data
var result = StudentAnalyzer.GetStudentsWithAverageBelow75(students); // Call method under
test

var fullNames = result.Select(r => r.FullName).ToList(); // Get full names from result

// Check that Bob Johnson and Dan Hall are in the result
CollectionAssert.Contains(fullNames, "Bob Johnson");
CollectionAssert.Contains(fullNames, "Dan Hall");

// Check that Alice Smith is NOT in the result (since her average is above 75)
CollectionAssert.DoesNotContain(fullNames, "Alice Smith");

// Additional checks: Verify that the average scores are actually below 75
var bob = result.FirstOrDefault(r => r.FullName == "Bob Johnson");
var dan = result.FirstOrDefault(r => r.FullName == "Dan Hall");
Assert.IsTrue(bob.AverageScore < 75); // Check Bob's average
Assert.IsTrue(dan.AverageScore < 75); // Check Dan's average
}

// Unit test to verify that GetStudentsWithSameFirstName groups students correctly


[TestMethod]
public void studentsWithSameFirstNameShouldReturnAliceGroup()
{
var students = getSampleStudents(); // Get sample data
var result = StudentAnalyzer.GetStudentsWithSameFirstName(students); // Group students by
first name
var aliceGroup = result.FirstOrDefault(g => g.FirstName == "Alice"); // Try to find a group where
the first name is "Alice"

Assert.IsNotNull(aliceGroup); // Ensure the group exists


Assert.AreEqual(2, aliceGroup.Students.Count); // Confirm there are 2 students named Alice
// Check the actual student names in the group
CollectionAssert.Contains(aliceGroup.Students, "Alice Smith");
CollectionAssert.Contains(aliceGroup.Students, "Alice Jones");
}

// Unit test to verify that GetSameGradeGroups includes a specific common grade


[TestMethod]
public void sameGradeGroupsShouldIncludeCommonGrade()
{
var students = getSampleStudents(); // Get sample data
var result = StudentAnalyzer.GetSameGradeGroups(students); // Group students by grades per
subject
// Find a group where the grade is 60 in subject index 1 (second subject)
var match = result.FirstOrDefault(g => g.Grade == 60 && g.SubjectIndex == 1);

Assert.IsNotNull(match); // Confirm such a group exists


// Verify that "Bob Johnson" and "Dan Hall" are in this grade group
CollectionAssert.Contains(match.FullNames, "Bob Johnson");
CollectionAssert.Contains(match.FullNames, "Dan Hall");
}
}
}

Explanation of each function

1. `GetStudentsWithAverageBelow75`

Purpose:
Finds and returns a list of students whose average score across all subjects is below 75.

Inputs:
`students`: List<Student> — a list of `Student` objects, each containing scores.

Outputs:
- List of `StudentResult` objects (or similar), each representing a student with:
- FullName
- AverageScore

How it works:
1. Calculate each student's average score:
- For each `Student`, sum their scores and divide by the number of scores.
2. Filter students:
- Select only those students whose average score is less than 75.
3. Create result objects:
- For each filtered student, create an object containing their full name and average score.

2. `GetStudentsWithSameFirstName`

Purpose:
Group students by their first names, returning groups where more than one student shares the same
first name.

Inputs:
- `students`: List<Student> — list of students.

Outputs:
- List of `FirstNameGroup` objects, each containing:
- `FirstName`
- List of student full names (`Students` or similar)

How it works:
1. Group students by FirstName:
- Use LINQ `GroupBy` on `FirstName`.
2. Filter groups:
- Keep only groups where the count of students > 1.
3. Create group objects:
- For each group, store the first name and the list of full names of students sharing that name.

3. `GetSameGradeGroups`

Purpose:
Group students based on their grade in each subject, identifying students who share the same score in
each subject.

Inputs:
- `students`: List<Student>

Outputs:
- List of `GradeGroup` objects, each containing:
- `SubjectIndex` (which subject)
- `Grade` (the score)
- List of students who have that grade in that subject (`FullNames`)
How it works:
1. Iterate over subjects:
- For each subject index (assuming fixed number of subjects), examine each student's score.
2. Group by score:
- For each subject, group students by their score.
3. Create groups:
- For each score, create a `GradeGroup` with subject index, grade, and list of students' full names.

Summary

Namespaces and Imports

These lines import necessary .NET and custom libraries. The `StudentAnalyzer` and `Student` classes are
assumed to be defined in `ClassLibrary1`.

Namespace and Test Class

`namespace UnitTesting`: Groups all test-related classes.


`[TestClass]`: Tells MSTest this class contains unit tests.

Helper Method to Provide Sample Data

-This private method returns a list of sample `Student` objects for reuse across multiple tests.

Test 1: Average Score Below 75

[TestMethod]
public void studentsWithAverageBelow75_ShouldReturnCorrectNamesAndGrades()

* This test checks if students with **average scores below 75** are properly returned.

var students = getSampleStudents();


var result = StudentAnalyzer.GetStudentsWithAverageBelow75(students);

* Calls the method under test with sample data.

var fullNames = result.Select(r => r.FullName).ToList();


* Extracts full names of returned students.

CollectionAssert.Contains(fullNames, "Bob Johnson");


CollectionAssert.Contains(fullNames, "Dan Hall");
CollectionAssert.DoesNotContain(fullNames, "Alice Smith");

* Ensures Bob and Dan (low scorers) are included, and Alice (a high scorer) is not.

var bob = result.FirstOrDefault(r => r.FullName == "Bob Johnson");


var dan = result.FirstOrDefault(r => r.FullName == "Dan Hall");
Assert.IsTrue(bob.AverageScore < 75);
Assert.IsTrue(dan.AverageScore < 75);

* Confirms that Bob and Dan’s average scores are actually below 75.

Test 2: Same First Name Grouping

[TestMethod]
public void studentsWithSameFirstName_ShouldReturnAliceGroup()
```

* This test verifies if students with the **same first name** are grouped correctly.

var students = getSampleStudents();


var result = StudentAnalyzer.GetStudentsWithSameFirstName(students);

* Calls method to get name groups.

var aliceGroup = result.FirstOrDefault(g => g.FirstName == "Alice");


Assert.IsNotNull(aliceGroup); // Group should exist
Assert.AreEqual(2, aliceGroup.Students.Count); // Should have 2 students
CollectionAssert.Contains(aliceGroup.Students, "Alice Smith");
CollectionAssert.Contains(aliceGroup.Students, "Alice Jones");

* Confirms that the "Alice" group exists and contains both Alice students.

Test 3: Common Grades in Same Subject**

[TestMethod]
public void sameGradeGroups_ShouldIncludeCommonGrade()

* This test checks if students who received the **same grade in the same subject** are grouped.

var students = getSampleStudents();


var result = StudentAnalyzer.GetSameGradeGroups(students);

* Calls method to find students with matching grades.

var match = result.FirstOrDefault(g => g.Grade == 60 && g.SubjectIndex == 1);


Assert.IsNotNull(match);
CollectionAssert.Contains(match.FullNames, "Bob Johnson");
CollectionAssert.Contains(match.FullNames, "Dan Hall");

* Looks for students who both scored **60 in Subject 2** (index 1).
* Ensures both Bob and Dan are included in that group.

This unit test file:

* Verifies students are filtered correctly by average score.


* Ensures students are grouped properly by first name.
* Confirms grade-based grouping by subject index and score.

These tests help **validate core logic** in the `StudentAnalyzer` class.

You might also like