using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
public delegate void NameChangedDelegate(object sender, NameChangedEventArgs args);
public static void Main(string[] args)
IGradeTracker book3 = CreateGradeBook();
public static IGradeTracker CreateGradeBook()
return new ThrowAwayGB();
public static void GradeBookName(IGradeTracker book)
Console.WriteLine("Please enter a name for the Grade Book:");
book.Name = Console.ReadLine();
catch(ArgumentException ex)
Console.WriteLine(ex.Message);
catch(NullReferenceException)
Console.WriteLine("Something went wrong!");
public static void AddGrades(IGradeTracker book)
public static void SaveGrades(IGradeTracker book)
using(StreamWriter fileOut = File.CreateText("grades.txt"))
book.WriteGrades(fileOut);
public static void ShowGrades(IGradeTracker book)
GradeStatistics stats = book.ComputeStatistics();
Console.WriteLine(book.Name + "'s GradeBook");
foreach(float grade in book)
Console.WriteLine(grade + " ");
WriteResult("Average", (int)stats.avgGrade);
WriteResult("Highest", stats.highestGrade);
WriteResult("Lowest", stats.lowestGrade);
WriteResult(stats.Description, stats.letterGrade);
static void OnNameChanged(object sender, NameChangedEventArgs args)
Console.WriteLine("Changed name from " + args.ExistingName + " to " + args.NewName);
static void WriteResult(string description, int result)
Console.WriteLine("{0}: {1:F2}", description, result);
static void WriteResult(string description, float result)
Console.WriteLine(description + ": " + result);
static void WriteResult(string description, string result)
Console.WriteLine(description + " " + result);
public class GradeBook : GradeTracker
protected List<float> grades;
public override IEnumerator GetEnumerator()
return grades.GetEnumerator();
grades = new List<float>();
public override void WriteGrades(TextWriter destination)
for(int i = 0; i < grades.Count; i++)
destination.WriteLine(grades[i]);
public override void AddGrade(float grade)
public override GradeStatistics ComputeStatistics()
GradeStatistics stats = new GradeStatistics();
foreach(float grade in grades)
stats.highestGrade = Math.Max(grade, stats.highestGrade);
stats.lowestGrade = Math.Min(grade, stats.lowestGrade);
stats.avgGrade = sum/grades.Count();
public class ThrowAwayGB : GradeBook
public override GradeStatistics ComputeStatistics()
float lowest = float.MaxValue;
foreach(float grade in grades)
lowest = Math.Min(grade, lowest);
return base.ComputeStatistics();
public class GradeStatistics
public float highestGrade;
public float lowestGrade;
lowestGrade = float.MaxValue;
public string letterGrade
public string Description
result = "Below-Average";
public class NameChangedEventArgs : EventArgs
public string ExistingName
public abstract class GradeTracker : IGradeTracker
public abstract void AddGrade(float grade);
public abstract GradeStatistics ComputeStatistics();
public abstract void WriteGrades(TextWriter destination);
public NameChangedDelegate NameChanged;
public abstract IEnumerator GetEnumerator();
if(string.IsNullOrEmpty(value))
throw new ArgumentException("Name cannot be null or empty");
if(_name != value && NameChanged != null)
NameChangedEventArgs args = new NameChangedEventArgs();
args.ExistingName = _name;
public interface IGradeTracker : IEnumerable
void AddGrade(float grade);
GradeStatistics ComputeStatistics();
void WriteGrades(TextWriter destination);