experimental_design.experimental_designs
experimental_designs is a module that acts as a collection point for tools to create and manage design of experiments (DOE), or statistical design of experiments. Currently, it has functions to produce fully factorial designs, with or without a center point, and in the whole plot /split plot methods.
1#----------------------------------------------------------------------------- 2# Name: experimental_designs 3# Purpose: To make design of experiments easy (DOE). 4# Authors: [email protected] 5# Created: 4/20/2021 6# License: MIT License 7#----------------------------------------------------------------------------- 8"""experimental_designs is a module that acts as a collection point for tools to create and manage 9design of experiments (DOE), or statistical design of experiments. Currently, it has 10functions to produce fully factorial designs, with or without a center point, and in 11the whole plot /split plot methods. 12""" 13#----------------------------------------------------------------------------- 14# Standard Imports 15import sys 16import os 17import random 18import itertools 19import yaml 20import pandas as pd 21 22#----------------------------------------------------------------------------- 23# Module Constants 24RANDOM_SEED = 42 25#----------------------------------------------------------------------------- 26# Module Functions 27def pretty_print_np(array): 28 """prints a numpy array the way I think looks best""" 29 outstring = "" 30 for index, element in enumerate(array): 31 if index == len(array) - 1: 32 outstring += str(element) + "" 33 else: 34 outstring += str(element) + ", " 35 return outstring 36 37 38def create_factor_table(dataframe): 39 """Given a dataframe prints off the unique values for the column names, 40 make sure the configuration number is index.""" 41 out_dictionary = {} 42 for column in dataframe.columns: 43 out_dictionary.update({column: dataframe[column].unique()}) 44 return out_dictionary 45 46 47def print_factor_table(dataframe): 48 """Given a dataframe prints off the unique values for the column names, 49 make sure the configuration number is index.""" 50 for column in dataframe.columns: 51 print("{0} : {1}".format(column, pretty_print_np(dataframe[column].unique()))) 52 53 54def jupyter_print_factor_table(dataframe, column_names=["Factors", "Values"]): 55 """Pretty prints a factor table in a jupyter notebook""" 56 from IPython.display import display, Markdown 57 58 output_string = r"<table>" + "\n" 59 heading = r"<TR><TH>{0}</TH><TH>{1}</TH></TR>".format(*column_names) 60 output_string += heading + "\n" 61 for column in dataframe.columns: 62 output_string += r"<TR><TD>{0}</TD><TD>{1}</TD></TR>".format(column, pretty_print_np( 63 sorted(dataframe[column].unique()))) + "\n" 64 ending = r"</table>" 65 output_string += ending 66 display(Markdown(output_string)) 67 68 69def get_variable_factors(dataframe): 70 """Given a dataframe, returns a list of factors that vary.""" 71 factors = [column for column in dataframe.columns if len(dataframe[column].unique()) > 1] 72 return factors 73 74def condition_in_row (row,condition): 75 """Truth function for filter. 76 Determines if condition is in row, returning True if it is not and False otherwise. """ 77 for condition_key,condition_value in condition.items(): 78 if row[condition_key]!=condition_value: 79 return True 80 return False 81 82def filter_rows(design,exclusions): 83 """Input a design of the form [{Row_1},...{RowN}] and an exclusions of the form [{exclusion_1}.. 84 {exclusion_N}] and returns a filter version of design.""" 85 out = design 86 for excluded in exclusions: 87 out = list(filter(lambda x: condition_in_row(x,excluded),out)) 88 return out 89 90def fully_factorial(design_dictionary, randomized=True, run_values="values",random_seed = RANDOM_SEED): 91 """Given a design_dictionary in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 92 'factor_name_N':{factor_level_N:factor_level_value_N}} 93 returns a test_conditions run sheet. Optional parameters are randomized (True or False) and run_values 94 ("keys" or "values"). The randomization process sets a random_seed = RANDOM_SEED to be reproducible. """ 95 factors = list(design_dictionary.keys()) 96 factor_values = [] 97 for factor in factors: 98 factor_values_row = list(design_dictionary[factor].__getattribute__(run_values)()) 99 factor_values.append(factor_values_row) 100 test_conditions = [dict(zip(factors, state)) for state in itertools.product(*factor_values)] 101 if randomized: 102 random.seed(random_seed) 103 random.shuffle(test_conditions) 104 return test_conditions 105 106 107def fully_factorial_default(design_dictionary, default_state, default_modulo=2, 108 randomized=True, run_values="values",random_seed =42): 109 """Given a design_dictionary in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 110 'factor_name_N':{factor_level_N:factor_level_value_N}} and a default state in the same format, 111 returns a test_conditions run sheet. Optional parameters are default_modulo (how often do you want the state, 112 randomized (True or False) and run_values. 113 ("keys" or "values"). """ 114 115 test_conditions = fully_factorial(design_dictionary, 116 randomized=randomized, 117 run_values=run_values, 118 random_seed=random_seed) 119 factors = list(design_dictionary.keys()) 120 default_condition = {} 121 for factor in factors: 122 default_condition[factor] = list(default_state[factor].__getattribute__(run_values)())[0] 123 defaulted_test_conditions = [] 124 for test_index, test_condition in enumerate(test_conditions): 125 if test_index % default_modulo == 0: 126 defaulted_test_conditions.append(default_condition) 127 defaulted_test_conditions.append(test_condition) 128 else: 129 defaulted_test_conditions.append(test_condition) 130 return defaulted_test_conditions 131 132 133def fully_factorial_split_plot(whole_plot_design_dictionary, split_plot_design_dictionary, 134 randomized=True, run_values="values",random_seed_base = RANDOM_SEED): 135 """Given a whole_plot_design_dictionary and split_plot_design_dictionary in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 136 'factor_name_N':{factor_level_N:factor_level_value_N}} , 137 returns a test_conditions run sheet. Optional parameters are 138 randomized (True or False) and run_values. 139 ("keys" or "values"). """ 140 test_conditions = [] 141 whole_plot_test_conditions = fully_factorial(whole_plot_design_dictionary, 142 randomized=randomized, 143 run_values=run_values) 144 for whole_plot_index,whole_plot in enumerate(whole_plot_test_conditions): 145 split_plot_test_condtions = fully_factorial(split_plot_design_dictionary, 146 randomized=randomized, 147 run_values=run_values, 148 random_seed=random_seed_base+whole_plot_index) 149 for split_plot in split_plot_test_condtions: 150 new_row = dict(whole_plot) 151 new_row.update(split_plot) 152 test_conditions.append(new_row) 153 return test_conditions 154 155 156def fully_factorial_split_plot_default(whole_plot_design_dictionary, split_plot_design_dictionary, 157 whole_plot_default_dictionary, whole_plot_default_modulo=2, 158 randomized=True, run_values="values"): 159 """Given a whole_plot_design_dictionary and split_plot_design_dictionary in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 160 'factor_name_N':{factor_level_N:factor_level_value_N}} and a default state in the same format, 161 returns a test_conditions run sheet. It assumes that the split plot design remains the same 162 Optional parameters are default_modulo (how often do you want the state in whole plot iterations, 163 randomized (True or False) and run_values. 164 ("keys" or "values"). """ 165 # Build the fully factorial test and default conditions 166 test_conditions = fully_factorial_split_plot(whole_plot_design_dictionary, split_plot_design_dictionary, 167 randomized=randomized, run_values=run_values) 168 169 default_conditions = fully_factorial_split_plot(whole_plot_default_dictionary, split_plot_design_dictionary, 170 randomized=randomized, run_values=run_values) 171 172 number_split_plot_states = 1 173 for factor in split_plot_design_dictionary.keys(): 174 number_split_plot_states = number_split_plot_states * len(split_plot_design_dictionary[factor]) 175 state_modulo = int(whole_plot_default_modulo * number_split_plot_states) 176 177 defaulted_test_conditions = [] 178 for test_index, test_condition in enumerate(test_conditions): 179 if test_index % state_modulo == 0: 180 for default_state in default_conditions: 181 defaulted_test_conditions.append(default_state) 182 defaulted_test_conditions.append(test_condition) 183 else: 184 defaulted_test_conditions.append(test_condition) 185 return defaulted_test_conditions 186 187def fully_factorial_split_plot_interleaved(whole_plot_design_dictionary, split_plot_design_dictionary, 188 whole_plot_design_dictionary_interleaved, 189 split_plot_design_dictionary_interleaved, 190 interleave_modulo=2, 191 randomized=True, run_values="values"): 192 """Given whole_plot_design_dictionary, split_plot_design_dictionary, 193 whole_plot_design_dictionary_interleaved, split_plot_design_dictionary_interleaved in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 194 'factor_name_N':{factor_level_N:factor_level_value_N}}, 195 returns a test_conditions run sheet. It assumes that the split plot design remains the same 196 Optional parameters are interleave_modulo (how often do you want the state in whole plot iterations, 197 randomized (True or False) and run_values. 198 ("keys" or "values"). """ 199 # Build the fully factorial test and default conditions 200 test_conditions = fully_factorial_split_plot(whole_plot_design_dictionary, split_plot_design_dictionary, 201 randomized=randomized, run_values=run_values) 202 203 # does this lead to a different randomization each time? -NO 204 205 206 number_split_plot_states = 1 207 for factor in split_plot_design_dictionary.keys(): 208 number_split_plot_states = number_split_plot_states * len(split_plot_design_dictionary[factor]) 209 state_modulo = int(interleave_modulo * number_split_plot_states) 210 211 interleaved_test_conditions = [] 212 for test_index, test_condition in enumerate(test_conditions): 213 if test_index % state_modulo == 0: 214 interleave_conditions = fully_factorial_split_plot(whole_plot_design_dictionary_interleaved, 215 split_plot_design_dictionary_interleaved, 216 randomized=randomized, 217 run_values=run_values, 218 random_seed_base=test_index) 219 for interleave_state in interleave_conditions: 220 interleaved_test_conditions.append(interleave_state) 221 interleaved_test_conditions.append(test_condition) 222 else: 223 interleaved_test_conditions.append(test_condition) 224 return interleaved_test_conditions 225 226#----------------------------------------------------------------------------- 227# Module Scripts 228def test_fully_factorial(): 229 """Tests the fully_factorial design""" 230 test_design = {'one': {0: 'LOW', 1: 'HIGH', 2: 'zest'}, 'two': {0: 'FAST', 1: 'SLOW'}, 'three': {0: 'ON'}} 231 print("*"*80) 232 print("Testing the fully_factorial function") 233 print(f"The test design is {yaml.dump(test_design)}") 234 test_condtions = pd.DataFrame(fully_factorial(test_design, randomized=False)) 235 test_condtions_keys = pd.DataFrame(fully_factorial(test_design, randomized=False, run_values="keys")) 236 random_test_condtions = pd.DataFrame(fully_factorial(test_design, randomized=True)) 237 print("The test_conditions or design when not randomized is:") 238 print(test_condtions) 239 print("*"*80) 240 print("The test_conditions or design in state numbers when not randomized is:") 241 print(test_condtions_keys) 242 print("*" * 80) 243 print("The test_conditions or design randomized is:") 244 print(random_test_condtions) 245 print("*" * 80) 246 247def test_fully_factorial_default(): 248 """Tests the fully_factorial_default design""" 249 test_design = {'one': {0: 'LOW', 1: 'HIGH', 2: 'zest'}, 'two': {0: 'FAST', 1: 'SLOW'}, 'three': {0: 'ON'}} 250 default = {'one': {-1: 'default'}, 'two': {-1: 'MEDIUM'}, 'three': {-1: 'OFF'}} 251 print("*"*80) 252 print("Testing the fully_factorial_default function") 253 print(f"The test design is {yaml.dump(test_design)}") 254 print(f"The default is {yaml.dump(default)}") 255 test_condtions = pd.DataFrame(fully_factorial_default(test_design, default , randomized=False)) 256 test_condtions_keys = pd.DataFrame(fully_factorial_default(test_design, default, randomized=False, run_values="keys")) 257 random_test_condtions = pd.DataFrame(fully_factorial_default(test_design, default, randomized=True)) 258 print("The test_conditions or design when not randomized is:") 259 print(test_condtions) 260 print("*"*80) 261 print("The test_conditions or design in state numbers when not randomized is:") 262 print(test_condtions_keys) 263 print("*" * 80) 264 print("The test_conditions or design randomized is:") 265 print(random_test_condtions) 266 print("*" * 80) 267 268def test_fully_factorial_split_plot(): 269 """Tests the fully_factorial_split_plot_default design""" 270 test_design = {'one': {0: 'LOW', 1: 'HIGH', 2: 'zest'}, 'two': {0: 'FAST', 1: 'SLOW'}, 'three': {0: 'ON'}} 271 wp = {'whole_plot_1': {-1: "in my shoe", 0: 'In my Head'}, 'whole_plot_2': {0: 'WP OFF', 1: "WP ON"}} 272 print("*"*80) 273 print("Testing the test_fully_factorial_split_plot_default function") 274 print(f"The test design is {yaml.dump(test_design)}") 275 print(f"The whole plot design is {yaml.dump(wp)}") 276 277 test_condtions = pd.DataFrame(fully_factorial_split_plot(whole_plot_design_dictionary=wp, 278 split_plot_design_dictionary = test_design, 279 randomized=False)) 280 test_condtions_keys = pd.DataFrame(fully_factorial_split_plot(whole_plot_design_dictionary=wp, 281 split_plot_design_dictionary = test_design, 282 randomized=False, 283 run_values="keys")) 284 random_test_condtions = pd.DataFrame(fully_factorial_split_plot(whole_plot_design_dictionary=wp, 285 split_plot_design_dictionary = test_design, 286 randomized=True, 287 run_values="values")) 288 print("The test_conditions or design when not randomized is:") 289 print(test_condtions) 290 print("*"*80) 291 print("The test_conditions or design in state numbers when not randomized is:") 292 print(test_condtions_keys) 293 print("*" * 80) 294 print("The test_conditions or design randomized is:") 295 print(random_test_condtions) 296 print("*" * 80) 297 298def test_fully_factorial_split_plot_default(): 299 """Tests the fully_factorial_split_plot_default design""" 300 301 test_design = {'one': {0: 'LOW', 1: 'HIGH', 2: 'zest'}, 'two': {0: 'FAST', 1: 'SLOW'}, 'three': {0: 'ON'}} 302 wp = {'whole_plot_1': {-1: "in my shoe", 0: 'In my Head'}, 'whole_plot_2': {0: 'WP OFF', 1: "WP ON"}} 303 wp_default = {'whole_plot_1': {3: "default"}, 'whole_plot_2': {0: 'wp_2 default'}} 304 print("*"*80) 305 print("Testing the test_fully_factorial_split_plot_default function") 306 print(f"The test design is {yaml.dump(test_design)}") 307 print(f"The whole plot design is {yaml.dump(wp)}") 308 print(f"The whole plot default is {yaml.dump(wp_default)}") 309 310 test_condtions = pd.DataFrame(fully_factorial_split_plot_default(whole_plot_design_dictionary=wp, 311 split_plot_design_dictionary = test_design, 312 whole_plot_default_dictionary=wp_default , 313 randomized=False)) 314 test_condtions_keys = pd.DataFrame(fully_factorial_split_plot_default(whole_plot_design_dictionary=wp, 315 split_plot_design_dictionary = test_design, 316 whole_plot_default_dictionary=wp_default , 317 randomized=False, 318 run_values="keys")) 319 random_test_condtions = pd.DataFrame(fully_factorial_split_plot_default(whole_plot_design_dictionary=wp, 320 split_plot_design_dictionary = test_design, 321 whole_plot_default_dictionary=wp_default , 322 randomized=True, 323 run_values="values")) 324 print("The test_conditions or design when not randomized is:") 325 print(test_condtions) 326 print("*"*80) 327 print("The test_conditions or design in state numbers when not randomized is:") 328 print(test_condtions_keys) 329 print("*" * 80) 330 print("The test_conditions or design randomized is:") 331 print(random_test_condtions) 332 print("*" * 80) 333 334def test_fully_factorial_split_plot_interleave(): 335 """Tests the fully_factorial_split_plot_default design""" 336 sp = {'one': {0: 'LOW', 1: 'HIGH', 2: 'zest'}, 'two': {0: 'FAST', 1: 'SLOW'}, 'three': {0: 'ON'}} 337 wp = {'whole_plot_1': {-1: "in my shoe", 0: 'In my Head'}, 'whole_plot_2': {0: 'WP OFF', 1: "WP ON"}} 338 wp_2 = {'whole_plot_1': {3: "default"}, 'whole_plot_2': {0: 'wp_2 default'}} 339 sp_2 = {'Atten': {0: 0, 1: 20, 2: 40}, 'two': {0: 'NEW', 1: 'OLD'}, 'three': {0: 'OFF'}} 340 print("*"*80) 341 print("Testing the test_fully_factorial_split_plot_default function") 342 print(f"The whole plot design is {yaml.dump(wp)}") 343 print(f"The split plot design is {yaml.dump(sp)}") 344 345 print(f"The second whole plot default is {yaml.dump(wp_2)}") 346 print(f"The second split plot default is {yaml.dump(sp_2)}") 347 348 test_condtions = pd.DataFrame(fully_factorial_split_plot_interleaved(whole_plot_design_dictionary=wp, 349 split_plot_design_dictionary = sp, 350 whole_plot_design_dictionary_interleaved= wp_2 , 351 split_plot_design_dictionary_interleaved = sp_2, 352 randomized=False)) 353 test_condtions_keys = pd.DataFrame(fully_factorial_split_plot_interleaved(whole_plot_design_dictionary=wp, 354 split_plot_design_dictionary = sp, 355 whole_plot_design_dictionary_interleaved= wp_2 , 356 split_plot_design_dictionary_interleaved = sp_2, 357 randomized=False, 358 run_values='keys')) 359 random_test_condtions = pd.DataFrame(fully_factorial_split_plot_interleaved(whole_plot_design_dictionary=wp, 360 split_plot_design_dictionary = sp, 361 whole_plot_design_dictionary_interleaved= wp_2 , 362 split_plot_design_dictionary_interleaved = sp_2, 363 randomized=True, 364 run_values='values')) 365 print("The test_conditions or design when not randomized is:") 366 print(test_condtions) 367 print("*"*80) 368 print("The test_conditions or design in state numbers when not randomized is:") 369 print(test_condtions_keys) 370 print("*" * 80) 371 print("The test_conditions or design randomized is:") 372 print(random_test_condtions) 373 print("*" * 80) 374 375#----------------------------------------------------------------------------- 376# Module Runner 377if __name__ == '__main__': 378 test_fully_factorial() 379 test_fully_factorial_default() 380 test_fully_factorial_split_plot() 381 test_fully_factorial_split_plot_interleave() 382
28def pretty_print_np(array): 29 """prints a numpy array the way I think looks best""" 30 outstring = "" 31 for index, element in enumerate(array): 32 if index == len(array) - 1: 33 outstring += str(element) + "" 34 else: 35 outstring += str(element) + ", " 36 return outstring
prints a numpy array the way I think looks best
39def create_factor_table(dataframe): 40 """Given a dataframe prints off the unique values for the column names, 41 make sure the configuration number is index.""" 42 out_dictionary = {} 43 for column in dataframe.columns: 44 out_dictionary.update({column: dataframe[column].unique()}) 45 return out_dictionary
Given a dataframe prints off the unique values for the column names, make sure the configuration number is index.
48def print_factor_table(dataframe): 49 """Given a dataframe prints off the unique values for the column names, 50 make sure the configuration number is index.""" 51 for column in dataframe.columns: 52 print("{0} : {1}".format(column, pretty_print_np(dataframe[column].unique())))
Given a dataframe prints off the unique values for the column names, make sure the configuration number is index.
55def jupyter_print_factor_table(dataframe, column_names=["Factors", "Values"]): 56 """Pretty prints a factor table in a jupyter notebook""" 57 from IPython.display import display, Markdown 58 59 output_string = r"<table>" + "\n" 60 heading = r"<TR><TH>{0}</TH><TH>{1}</TH></TR>".format(*column_names) 61 output_string += heading + "\n" 62 for column in dataframe.columns: 63 output_string += r"<TR><TD>{0}</TD><TD>{1}</TD></TR>".format(column, pretty_print_np( 64 sorted(dataframe[column].unique()))) + "\n" 65 ending = r"</table>" 66 output_string += ending 67 display(Markdown(output_string))
Pretty prints a factor table in a jupyter notebook
70def get_variable_factors(dataframe): 71 """Given a dataframe, returns a list of factors that vary.""" 72 factors = [column for column in dataframe.columns if len(dataframe[column].unique()) > 1] 73 return factors
Given a dataframe, returns a list of factors that vary.
75def condition_in_row (row,condition): 76 """Truth function for filter. 77 Determines if condition is in row, returning True if it is not and False otherwise. """ 78 for condition_key,condition_value in condition.items(): 79 if row[condition_key]!=condition_value: 80 return True 81 return False
Truth function for filter. Determines if condition is in row, returning True if it is not and False otherwise.
83def filter_rows(design,exclusions): 84 """Input a design of the form [{Row_1},...{RowN}] and an exclusions of the form [{exclusion_1}.. 85 {exclusion_N}] and returns a filter version of design.""" 86 out = design 87 for excluded in exclusions: 88 out = list(filter(lambda x: condition_in_row(x,excluded),out)) 89 return out
Input a design of the form [{Row_1},...{RowN}] and an exclusions of the form [{exclusion_1}.. {exclusion_N}] and returns a filter version of design.
91def fully_factorial(design_dictionary, randomized=True, run_values="values",random_seed = RANDOM_SEED): 92 """Given a design_dictionary in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 93 'factor_name_N':{factor_level_N:factor_level_value_N}} 94 returns a test_conditions run sheet. Optional parameters are randomized (True or False) and run_values 95 ("keys" or "values"). The randomization process sets a random_seed = RANDOM_SEED to be reproducible. """ 96 factors = list(design_dictionary.keys()) 97 factor_values = [] 98 for factor in factors: 99 factor_values_row = list(design_dictionary[factor].__getattribute__(run_values)()) 100 factor_values.append(factor_values_row) 101 test_conditions = [dict(zip(factors, state)) for state in itertools.product(*factor_values)] 102 if randomized: 103 random.seed(random_seed) 104 random.shuffle(test_conditions) 105 return test_conditions
Given a design_dictionary in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 'factor_name_N':{factor_level_N:factor_level_value_N}} returns a test_conditions run sheet. Optional parameters are randomized (True or False) and run_values ("keys" or "values"). The randomization process sets a random_seed = RANDOM_SEED to be reproducible.
108def fully_factorial_default(design_dictionary, default_state, default_modulo=2, 109 randomized=True, run_values="values",random_seed =42): 110 """Given a design_dictionary in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 111 'factor_name_N':{factor_level_N:factor_level_value_N}} and a default state in the same format, 112 returns a test_conditions run sheet. Optional parameters are default_modulo (how often do you want the state, 113 randomized (True or False) and run_values. 114 ("keys" or "values"). """ 115 116 test_conditions = fully_factorial(design_dictionary, 117 randomized=randomized, 118 run_values=run_values, 119 random_seed=random_seed) 120 factors = list(design_dictionary.keys()) 121 default_condition = {} 122 for factor in factors: 123 default_condition[factor] = list(default_state[factor].__getattribute__(run_values)())[0] 124 defaulted_test_conditions = [] 125 for test_index, test_condition in enumerate(test_conditions): 126 if test_index % default_modulo == 0: 127 defaulted_test_conditions.append(default_condition) 128 defaulted_test_conditions.append(test_condition) 129 else: 130 defaulted_test_conditions.append(test_condition) 131 return defaulted_test_conditions
Given a design_dictionary in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 'factor_name_N':{factor_level_N:factor_level_value_N}} and a default state in the same format, returns a test_conditions run sheet. Optional parameters are default_modulo (how often do you want the state, randomized (True or False) and run_values. ("keys" or "values").
134def fully_factorial_split_plot(whole_plot_design_dictionary, split_plot_design_dictionary, 135 randomized=True, run_values="values",random_seed_base = RANDOM_SEED): 136 """Given a whole_plot_design_dictionary and split_plot_design_dictionary in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 137 'factor_name_N':{factor_level_N:factor_level_value_N}} , 138 returns a test_conditions run sheet. Optional parameters are 139 randomized (True or False) and run_values. 140 ("keys" or "values"). """ 141 test_conditions = [] 142 whole_plot_test_conditions = fully_factorial(whole_plot_design_dictionary, 143 randomized=randomized, 144 run_values=run_values) 145 for whole_plot_index,whole_plot in enumerate(whole_plot_test_conditions): 146 split_plot_test_condtions = fully_factorial(split_plot_design_dictionary, 147 randomized=randomized, 148 run_values=run_values, 149 random_seed=random_seed_base+whole_plot_index) 150 for split_plot in split_plot_test_condtions: 151 new_row = dict(whole_plot) 152 new_row.update(split_plot) 153 test_conditions.append(new_row) 154 return test_conditions
Given a whole_plot_design_dictionary and split_plot_design_dictionary in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 'factor_name_N':{factor_level_N:factor_level_value_N}} , returns a test_conditions run sheet. Optional parameters are randomized (True or False) and run_values. ("keys" or "values").
157def fully_factorial_split_plot_default(whole_plot_design_dictionary, split_plot_design_dictionary, 158 whole_plot_default_dictionary, whole_plot_default_modulo=2, 159 randomized=True, run_values="values"): 160 """Given a whole_plot_design_dictionary and split_plot_design_dictionary in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 161 'factor_name_N':{factor_level_N:factor_level_value_N}} and a default state in the same format, 162 returns a test_conditions run sheet. It assumes that the split plot design remains the same 163 Optional parameters are default_modulo (how often do you want the state in whole plot iterations, 164 randomized (True or False) and run_values. 165 ("keys" or "values"). """ 166 # Build the fully factorial test and default conditions 167 test_conditions = fully_factorial_split_plot(whole_plot_design_dictionary, split_plot_design_dictionary, 168 randomized=randomized, run_values=run_values) 169 170 default_conditions = fully_factorial_split_plot(whole_plot_default_dictionary, split_plot_design_dictionary, 171 randomized=randomized, run_values=run_values) 172 173 number_split_plot_states = 1 174 for factor in split_plot_design_dictionary.keys(): 175 number_split_plot_states = number_split_plot_states * len(split_plot_design_dictionary[factor]) 176 state_modulo = int(whole_plot_default_modulo * number_split_plot_states) 177 178 defaulted_test_conditions = [] 179 for test_index, test_condition in enumerate(test_conditions): 180 if test_index % state_modulo == 0: 181 for default_state in default_conditions: 182 defaulted_test_conditions.append(default_state) 183 defaulted_test_conditions.append(test_condition) 184 else: 185 defaulted_test_conditions.append(test_condition) 186 return defaulted_test_conditions
Given a whole_plot_design_dictionary and split_plot_design_dictionary in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 'factor_name_N':{factor_level_N:factor_level_value_N}} and a default state in the same format, returns a test_conditions run sheet. It assumes that the split plot design remains the same Optional parameters are default_modulo (how often do you want the state in whole plot iterations, randomized (True or False) and run_values. ("keys" or "values").
188def fully_factorial_split_plot_interleaved(whole_plot_design_dictionary, split_plot_design_dictionary, 189 whole_plot_design_dictionary_interleaved, 190 split_plot_design_dictionary_interleaved, 191 interleave_modulo=2, 192 randomized=True, run_values="values"): 193 """Given whole_plot_design_dictionary, split_plot_design_dictionary, 194 whole_plot_design_dictionary_interleaved, split_plot_design_dictionary_interleaved in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 195 'factor_name_N':{factor_level_N:factor_level_value_N}}, 196 returns a test_conditions run sheet. It assumes that the split plot design remains the same 197 Optional parameters are interleave_modulo (how often do you want the state in whole plot iterations, 198 randomized (True or False) and run_values. 199 ("keys" or "values"). """ 200 # Build the fully factorial test and default conditions 201 test_conditions = fully_factorial_split_plot(whole_plot_design_dictionary, split_plot_design_dictionary, 202 randomized=randomized, run_values=run_values) 203 204 # does this lead to a different randomization each time? -NO 205 206 207 number_split_plot_states = 1 208 for factor in split_plot_design_dictionary.keys(): 209 number_split_plot_states = number_split_plot_states * len(split_plot_design_dictionary[factor]) 210 state_modulo = int(interleave_modulo * number_split_plot_states) 211 212 interleaved_test_conditions = [] 213 for test_index, test_condition in enumerate(test_conditions): 214 if test_index % state_modulo == 0: 215 interleave_conditions = fully_factorial_split_plot(whole_plot_design_dictionary_interleaved, 216 split_plot_design_dictionary_interleaved, 217 randomized=randomized, 218 run_values=run_values, 219 random_seed_base=test_index) 220 for interleave_state in interleave_conditions: 221 interleaved_test_conditions.append(interleave_state) 222 interleaved_test_conditions.append(test_condition) 223 else: 224 interleaved_test_conditions.append(test_condition) 225 return interleaved_test_conditions
Given whole_plot_design_dictionary, split_plot_design_dictionary, whole_plot_design_dictionary_interleaved, split_plot_design_dictionary_interleaved in the form {'factor_name_1':{factor_level_1:factor_level_value_1}, ... 'factor_name_N':{factor_level_N:factor_level_value_N}}, returns a test_conditions run sheet. It assumes that the split plot design remains the same Optional parameters are interleave_modulo (how often do you want the state in whole plot iterations, randomized (True or False) and run_values. ("keys" or "values").
229def test_fully_factorial(): 230 """Tests the fully_factorial design""" 231 test_design = {'one': {0: 'LOW', 1: 'HIGH', 2: 'zest'}, 'two': {0: 'FAST', 1: 'SLOW'}, 'three': {0: 'ON'}} 232 print("*"*80) 233 print("Testing the fully_factorial function") 234 print(f"The test design is {yaml.dump(test_design)}") 235 test_condtions = pd.DataFrame(fully_factorial(test_design, randomized=False)) 236 test_condtions_keys = pd.DataFrame(fully_factorial(test_design, randomized=False, run_values="keys")) 237 random_test_condtions = pd.DataFrame(fully_factorial(test_design, randomized=True)) 238 print("The test_conditions or design when not randomized is:") 239 print(test_condtions) 240 print("*"*80) 241 print("The test_conditions or design in state numbers when not randomized is:") 242 print(test_condtions_keys) 243 print("*" * 80) 244 print("The test_conditions or design randomized is:") 245 print(random_test_condtions) 246 print("*" * 80)
Tests the fully_factorial design
248def test_fully_factorial_default(): 249 """Tests the fully_factorial_default design""" 250 test_design = {'one': {0: 'LOW', 1: 'HIGH', 2: 'zest'}, 'two': {0: 'FAST', 1: 'SLOW'}, 'three': {0: 'ON'}} 251 default = {'one': {-1: 'default'}, 'two': {-1: 'MEDIUM'}, 'three': {-1: 'OFF'}} 252 print("*"*80) 253 print("Testing the fully_factorial_default function") 254 print(f"The test design is {yaml.dump(test_design)}") 255 print(f"The default is {yaml.dump(default)}") 256 test_condtions = pd.DataFrame(fully_factorial_default(test_design, default , randomized=False)) 257 test_condtions_keys = pd.DataFrame(fully_factorial_default(test_design, default, randomized=False, run_values="keys")) 258 random_test_condtions = pd.DataFrame(fully_factorial_default(test_design, default, randomized=True)) 259 print("The test_conditions or design when not randomized is:") 260 print(test_condtions) 261 print("*"*80) 262 print("The test_conditions or design in state numbers when not randomized is:") 263 print(test_condtions_keys) 264 print("*" * 80) 265 print("The test_conditions or design randomized is:") 266 print(random_test_condtions) 267 print("*" * 80)
Tests the fully_factorial_default design
269def test_fully_factorial_split_plot(): 270 """Tests the fully_factorial_split_plot_default design""" 271 test_design = {'one': {0: 'LOW', 1: 'HIGH', 2: 'zest'}, 'two': {0: 'FAST', 1: 'SLOW'}, 'three': {0: 'ON'}} 272 wp = {'whole_plot_1': {-1: "in my shoe", 0: 'In my Head'}, 'whole_plot_2': {0: 'WP OFF', 1: "WP ON"}} 273 print("*"*80) 274 print("Testing the test_fully_factorial_split_plot_default function") 275 print(f"The test design is {yaml.dump(test_design)}") 276 print(f"The whole plot design is {yaml.dump(wp)}") 277 278 test_condtions = pd.DataFrame(fully_factorial_split_plot(whole_plot_design_dictionary=wp, 279 split_plot_design_dictionary = test_design, 280 randomized=False)) 281 test_condtions_keys = pd.DataFrame(fully_factorial_split_plot(whole_plot_design_dictionary=wp, 282 split_plot_design_dictionary = test_design, 283 randomized=False, 284 run_values="keys")) 285 random_test_condtions = pd.DataFrame(fully_factorial_split_plot(whole_plot_design_dictionary=wp, 286 split_plot_design_dictionary = test_design, 287 randomized=True, 288 run_values="values")) 289 print("The test_conditions or design when not randomized is:") 290 print(test_condtions) 291 print("*"*80) 292 print("The test_conditions or design in state numbers when not randomized is:") 293 print(test_condtions_keys) 294 print("*" * 80) 295 print("The test_conditions or design randomized is:") 296 print(random_test_condtions) 297 print("*" * 80)
Tests the fully_factorial_split_plot_default design
299def test_fully_factorial_split_plot_default(): 300 """Tests the fully_factorial_split_plot_default design""" 301 302 test_design = {'one': {0: 'LOW', 1: 'HIGH', 2: 'zest'}, 'two': {0: 'FAST', 1: 'SLOW'}, 'three': {0: 'ON'}} 303 wp = {'whole_plot_1': {-1: "in my shoe", 0: 'In my Head'}, 'whole_plot_2': {0: 'WP OFF', 1: "WP ON"}} 304 wp_default = {'whole_plot_1': {3: "default"}, 'whole_plot_2': {0: 'wp_2 default'}} 305 print("*"*80) 306 print("Testing the test_fully_factorial_split_plot_default function") 307 print(f"The test design is {yaml.dump(test_design)}") 308 print(f"The whole plot design is {yaml.dump(wp)}") 309 print(f"The whole plot default is {yaml.dump(wp_default)}") 310 311 test_condtions = pd.DataFrame(fully_factorial_split_plot_default(whole_plot_design_dictionary=wp, 312 split_plot_design_dictionary = test_design, 313 whole_plot_default_dictionary=wp_default , 314 randomized=False)) 315 test_condtions_keys = pd.DataFrame(fully_factorial_split_plot_default(whole_plot_design_dictionary=wp, 316 split_plot_design_dictionary = test_design, 317 whole_plot_default_dictionary=wp_default , 318 randomized=False, 319 run_values="keys")) 320 random_test_condtions = pd.DataFrame(fully_factorial_split_plot_default(whole_plot_design_dictionary=wp, 321 split_plot_design_dictionary = test_design, 322 whole_plot_default_dictionary=wp_default , 323 randomized=True, 324 run_values="values")) 325 print("The test_conditions or design when not randomized is:") 326 print(test_condtions) 327 print("*"*80) 328 print("The test_conditions or design in state numbers when not randomized is:") 329 print(test_condtions_keys) 330 print("*" * 80) 331 print("The test_conditions or design randomized is:") 332 print(random_test_condtions) 333 print("*" * 80)
Tests the fully_factorial_split_plot_default design
335def test_fully_factorial_split_plot_interleave(): 336 """Tests the fully_factorial_split_plot_default design""" 337 sp = {'one': {0: 'LOW', 1: 'HIGH', 2: 'zest'}, 'two': {0: 'FAST', 1: 'SLOW'}, 'three': {0: 'ON'}} 338 wp = {'whole_plot_1': {-1: "in my shoe", 0: 'In my Head'}, 'whole_plot_2': {0: 'WP OFF', 1: "WP ON"}} 339 wp_2 = {'whole_plot_1': {3: "default"}, 'whole_plot_2': {0: 'wp_2 default'}} 340 sp_2 = {'Atten': {0: 0, 1: 20, 2: 40}, 'two': {0: 'NEW', 1: 'OLD'}, 'three': {0: 'OFF'}} 341 print("*"*80) 342 print("Testing the test_fully_factorial_split_plot_default function") 343 print(f"The whole plot design is {yaml.dump(wp)}") 344 print(f"The split plot design is {yaml.dump(sp)}") 345 346 print(f"The second whole plot default is {yaml.dump(wp_2)}") 347 print(f"The second split plot default is {yaml.dump(sp_2)}") 348 349 test_condtions = pd.DataFrame(fully_factorial_split_plot_interleaved(whole_plot_design_dictionary=wp, 350 split_plot_design_dictionary = sp, 351 whole_plot_design_dictionary_interleaved= wp_2 , 352 split_plot_design_dictionary_interleaved = sp_2, 353 randomized=False)) 354 test_condtions_keys = pd.DataFrame(fully_factorial_split_plot_interleaved(whole_plot_design_dictionary=wp, 355 split_plot_design_dictionary = sp, 356 whole_plot_design_dictionary_interleaved= wp_2 , 357 split_plot_design_dictionary_interleaved = sp_2, 358 randomized=False, 359 run_values='keys')) 360 random_test_condtions = pd.DataFrame(fully_factorial_split_plot_interleaved(whole_plot_design_dictionary=wp, 361 split_plot_design_dictionary = sp, 362 whole_plot_design_dictionary_interleaved= wp_2 , 363 split_plot_design_dictionary_interleaved = sp_2, 364 randomized=True, 365 run_values='values')) 366 print("The test_conditions or design when not randomized is:") 367 print(test_condtions) 368 print("*"*80) 369 print("The test_conditions or design in state numbers when not randomized is:") 370 print(test_condtions_keys) 371 print("*" * 80) 372 print("The test_conditions or design randomized is:") 373 print(random_test_condtions) 374 print("*" * 80)
Tests the fully_factorial_split_plot_default design