Created
September 23, 2010 18:33
-
-
Save joshpeterson/594106 to your computer and use it in GitHub Desktop.
Use a class hierarchy to create some simple statistics operations as an example in the first chapter of The D Programming Language does.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Reflection; | |
namespace StatisticsMethods | |
{ | |
interface StatisticsMethod | |
{ | |
void Accumulate(double value); | |
void PostProcess(); | |
double GetResult(); | |
} | |
public abstract class IncrementalStatisticsMethod : StatisticsMethod | |
{ | |
protected double result = 0.0; | |
public virtual void Accumulate(double value) { } | |
public virtual void PostProcess() { } | |
public virtual double GetResult() { return this.result; } | |
} | |
public sealed class Min : IncrementalStatisticsMethod | |
{ | |
public Min() | |
{ | |
this.result = double.MaxValue; | |
} | |
public override void Accumulate(double value) | |
{ | |
if (value < this.result) | |
{ | |
this.result = value; | |
} | |
} | |
} | |
public sealed class Max : IncrementalStatisticsMethod | |
{ | |
public Max() | |
{ | |
this.result = double.MinValue; | |
} | |
public override void Accumulate(double value) | |
{ | |
if (value > this.result) | |
{ | |
this.result = value; | |
} | |
} | |
} | |
public sealed class Average : IncrementalStatisticsMethod | |
{ | |
private int numberOfValues = 0; | |
public override void Accumulate(double value) | |
{ | |
numberOfValues++; | |
this.result += value; | |
} | |
public override void PostProcess() | |
{ | |
if (numberOfValues != 0) | |
{ | |
this.result = this.result / numberOfValues; | |
} | |
} | |
} | |
class SimpleStatisticsMethods | |
{ | |
static void Main(string[] args) | |
{ | |
if (args[0] == "Test") | |
{ | |
TestStatisticsMethods(); | |
return; | |
} | |
Dictionary<string, StatisticsMethod> statsMethods = GetStatisticsMethods(args); | |
List<double> values = GetValuesFromStandardInput(); | |
ProcessAllStatisticsMethods(values, statsMethods); | |
} | |
private static Dictionary<string, StatisticsMethod> GetStatisticsMethods(string[] args) | |
{ | |
Dictionary<string, StatisticsMethod> statsMethods = new Dictionary<string, StatisticsMethod>(); | |
for (int i = 0; i < args.Length; ++i) | |
{ | |
StatisticsMethod method = (StatisticsMethod)Activator.CreateInstance(Assembly.GetExecutingAssembly().FullName, string.Format("StatisticsMethods.{0}", args[i])).Unwrap(); | |
if (method != null) | |
{ | |
statsMethods.Add(args[i], method); | |
} | |
else | |
{ | |
Console.WriteLine("Unknown statistics method: {0}", args[i]); | |
} | |
} | |
return statsMethods; | |
} | |
private static List<double> GetValuesFromStandardInput() | |
{ | |
List<double> values = new List<double>(); | |
string line; | |
while ((line = Console.ReadLine()) != null) | |
{ | |
foreach (string input in line.Split(' ')) | |
{ | |
string trimmedInput = input.Trim(); | |
if (!string.IsNullOrEmpty(trimmedInput)) | |
{ | |
double value; | |
if (double.TryParse(trimmedInput, out value)) | |
{ | |
values.Add(value); | |
} | |
else | |
{ | |
Console.WriteLine("It doesn't look like {0} is a number, I'm skipping it.", input); | |
} | |
} | |
} | |
} | |
return values; | |
} | |
private static void ProcessAllStatisticsMethods(IEnumerable<double> values, IDictionary<string, StatisticsMethod> statsMethods) | |
{ | |
foreach (string statsMethodName in statsMethods.Keys) | |
{ | |
Console.WriteLine("{0}: {1}", statsMethodName,ProcessStatisticsMethod(values, statsMethods[statsMethodName])); | |
} | |
} | |
private static double ProcessStatisticsMethod(IEnumerable<double> values, StatisticsMethod statsMethod) | |
{ | |
foreach (double value in values) | |
{ | |
statsMethod.Accumulate(value); | |
} | |
statsMethod.PostProcess(); | |
return statsMethod.GetResult(); | |
} | |
private static void TestStatisticsMethods() | |
{ | |
double[] testValues = { 1.2, 2, 3.4, 4, 5.1, 6.8, 0.5, 1 }; | |
Console.WriteLine("Statistics method {0} test {1}", "Min", ProcessStatisticsMethod(testValues, new Min()) == 0.5 ? "passed" : "failed"); | |
Console.WriteLine("Statistics method {0} test {1}", "Max", ProcessStatisticsMethod(testValues, new Max()) == 6.8 ? "passed" : "failed"); | |
Console.WriteLine("Statistics method {0} test {1}", "Average", ProcessStatisticsMethod(testValues, new Average()) == 3.0 ? "passed" : "failed"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment