I'm running into a design problem. My code is in C# but the concepts could apply to any OO language.
I'm designing a framework to run experiments, and these experiments have several variables which we will manipulate, and several variables that we will calculate after manipulation (like columns in an excel sheet). Each variable can have a certain number of possible values. I need to store these variables somehow in a particular order. Then, I will need to create a row of data (one row of the hypothetical excel sheet) using the defined order, where I choose a single value of each variable, and calculate some of the variable values.
EDIT: Based on comments it sounds like I need to explain the purpose. Users should be able to input their experimental design, meaning which variables they want, and what the levels of each variable are. Then my program makes every permutation of those (trials), randomizes the trials, and then iterates through them for the experiment. The output is all just a .csv string. So after each trial it outputs the value of each input variable, and then calculates and outputs the output variables.
I have it all working right now. But at the moment, I need to define the variables manually for the users, and then they can put a list of values in for each on their own. I also have to manually write conversions to strings for each variable, and then manually put them into the correct order and alignment for the csv file. My end goal is to allow them to create their own variables and add it to the experiment without my intervention, and force an implemetation of string output.
what I have:
List<float> levels = new List<float>();
levels.add(1f);
levels.add(2f);
levels.add(3f);
Experiment.variable1.levels = levels;
what I want:
Experiment.AddVariable(new Variable<float>(levels);
// note that Variable should conceivably be any type
// and all variables types should have a method to output its value as a
// string depending on what type it is.
So i'll have something like:
inputvariable1 named "distance" has int
values:
1, 2
inputvariable2 named "time given" has float
values:
1.1, 1.2, 1.3
inputvariable3 named "some unknown class" has some user-defined values:
CustomClass.OnOffEnum.ON, CustomClass.OnOffEnum.OFF
ouputvariable1 named "response time" has float values:
So I have a class Variable
public class Variable<T> {
string name
T value
}
Now, I need to somehow store these variables, so I created a Row class:
public class Row {
List<Variable> variables;
public Row(List<Variable> variables) {
this.variables = variables
}
}
Now I have a couple problems:
1. How can I define a structure for Rows for each experiment, so that all Rows in a particular experiment will have the same variables in the same order? (same names, different values).
To tackle this problem I considered modifying Row
to require an inputted RowSchema
object to force it to define a certain schema for its variables. But I have now clue what RowShema
class should look like.
2. How can I ensure that each Variable implements a method StringOutput()
that I can use to write to a text file?
I considered forcing Variable
's generic type T to implement an interface with this method, but I want Variable
to be able to be a primitive type too.
something like
public class Variable<T> where T : StringOutputter {
I considered also just using ToString()
, but then for custom types, I can't ensure it will be a defined format.
3. It would be nice in other parts of my program to be able to refer to the value of particular variable (by name) of a particular row. Something like this:
row2.<<variablename>>.value
I've pondered this for several days, but can't figure out the correct architecture.
My current implementation is to manually define each Row
with fields representing each variable I want. But this is not extendable since I need to redefine the Row
class for each experiment.