From 659ffd9b73cff9e9e5f5a0d25bb46957e39aa009 Mon Sep 17 00:00:00 2001 From: alperaltuntas Date: Mon, 24 Jul 2023 18:12:02 -0600 Subject: [PATCH 1/2] refactor the reduce method in accordance with the Alloy model --- CIME/ParamGen/paramgen.py | 81 +++++++++++++-------------------------- 1 file changed, 26 insertions(+), 55 deletions(-) diff --git a/CIME/ParamGen/paramgen.py b/CIME/ParamGen/paramgen.py index 4fa6221f06e..b94f0b82808 100644 --- a/CIME/ParamGen/paramgen.py +++ b/CIME/ParamGen/paramgen.py @@ -280,7 +280,7 @@ def _expand_vars(expr, expand_func): return expr @staticmethod - def _is_guarded_dict(data_dict): + def is_guarded_dict(data_dict): """Returns true if all the keys of a dictionary are logical expressions, i.e., guards. Parameters @@ -290,11 +290,11 @@ def _is_guarded_dict(data_dict): Example ------- - >>> ParamGen._is_guarded_dict({True: 'x', 'False': 'y'}) + >>> ParamGen.is_guarded_dict({True: 'x', 'False': 'y'}) True - >>> ParamGen._is_guarded_dict({ "'tx0.66v1' == 'tx0.66v1'": 'x', False: 'y'}) + >>> ParamGen.is_guarded_dict({ "'tx0.66v1' == 'tx0.66v1'": 'x', False: 'y'}) True - >>> ParamGen._is_guarded_dict({'i':'x', 'j':'y'}) + >>> ParamGen.is_guarded_dict({'i':'x', 'j':'y'}) False """ if not isinstance(data_dict, dict): @@ -352,7 +352,7 @@ def _eval_guard(guard): ) return guard_evaluated - if not ParamGen._is_guarded_dict(data_dict): + if not ParamGen.is_guarded_dict(data_dict): return data_dict guards_eval_true = [] # list of guards that evaluate to true. @@ -370,65 +370,36 @@ def _eval_guard(guard): if self._match == "last": return data_dict[guards_eval_true[-1]] raise RuntimeError("Unknown match option.") - - def _reduce_recursive(self, data_dict, expand_func=None): - + + def _reduce_recursive(self, data, expand_func=None): """A recursive method to reduce a given data_dict. This method is intended to be called by the reduce method only. Check the docstring of the reduce method for more information.""" - # (1) Expand variables in keys, .e.g, "$OCN_GRID" to "gx1v7": - def _expand_vars_in_keys(data_dict): - if expand_func is not None: - new_data_dict = {} - for key in data_dict: - new_key = key - if has_unexpanded_var(key): - new_key = ParamGen._expand_vars(key, expand_func) - new_data_dict[new_key] = data_dict[key] - return new_data_dict - return data_dict - - data_dict = _expand_vars_in_keys(data_dict) + if isinstance(data, dict): - # (2) Evaluate the keys if they are all logical expressions, i.e., guards. - # Pick the value of the first or last key evaluating to True and drop everything else. - while ParamGen._is_guarded_dict(data_dict): - data_dict = self._impose_guards(data_dict) - if isinstance(data_dict, dict): - data_dict = _expand_vars_in_keys(data_dict) - - # If the data_dict is reduced to a string, expand vars and eval formulas as a last step. - if isinstance(data_dict, str): - - # (3) Expand variables in values, .e.g, "$OCN_GRID" to "gx1v7": - data_dict = ParamGen._expand_vars(data_dict, expand_func) - - # (4) Evaluate the formulas as values, e.g., "= 3+4", "= [i for i in range(5)]", etc. - if is_formula(data_dict): - data_dict = eval_formula(data_dict.strip()[1:]) + # (1) Expand vars in keys + if expand_func is not None: + data = {ParamGen._expand_vars(key, expand_func) : data[key] for key in data} - # Continue reducing the data if it is still a dictionary (nested or not). - elif isinstance(data_dict, dict): + # (2) Evaulate guards (if applicable) + if ParamGen.is_guarded_dict(data): + data = self._reduce_recursive(self._impose_guards(data), expand_func) - # (3) Expand variables in values, .e.g, "$OCN_GRID" to "gx1v7": - for key, val in data_dict.copy().items(): - if isinstance(val, str): - data_dict[key] = ParamGen._expand_vars(val, expand_func) + # (3) Call _reduce_recursive for all branches of dict + else: + for key in data: + data[key] = self._reduce_recursive(data[key], expand_func) - # (4) Evaluate the formulas as values, e.g., "= 3+4", "= [i for i in range(5)]", etc. - for key, val in data_dict.copy().items(): - if is_formula(val): - data_dict[key] = eval_formula(val.strip()[1:]) + else: # data is not a dict, and so is a value. - # (5) Recursively call _reduce_recursive for the remaining nested dicts before returning - keys_of_nested_dicts = [] # i.e., keys of values that are of type dict - for key, val in data_dict.items(): - if isinstance(val, dict): - keys_of_nested_dicts.append(key) - for key in keys_of_nested_dicts: - data_dict[key] = self._reduce_recursive(data_dict[key], expand_func) + # (4) Finally, process values by expanding vars and applying formulas + if isinstance(data, str): + data = ParamGen._expand_vars(data, expand_func) + if is_formula(data): + data = eval_formula(data.strip()[1:]) + + return data - return data_dict def reduce(self, expand_func=None): """ From fc34aef251d7013100bff17c4a3d00a7e7beaa62 Mon Sep 17 00:00:00 2001 From: alperaltuntas Date: Mon, 4 Mar 2024 20:43:45 -0700 Subject: [PATCH 2/2] run black formatter for paramgen.py --- CIME/ParamGen/paramgen.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/CIME/ParamGen/paramgen.py b/CIME/ParamGen/paramgen.py index 35a3ac5f6f7..16c735577e1 100644 --- a/CIME/ParamGen/paramgen.py +++ b/CIME/ParamGen/paramgen.py @@ -369,7 +369,7 @@ def _eval_guard(guard): if self._match == "last": return data_dict[guards_eval_true[-1]] raise RuntimeError("Unknown match option.") - + def _reduce_recursive(self, data, expand_func=None): """A recursive method to reduce a given data_dict. This method is intended to be called by the reduce method only. Check the docstring of the reduce method for more information.""" @@ -378,7 +378,9 @@ def _reduce_recursive(self, data, expand_func=None): # (1) Expand vars in keys if expand_func is not None: - data = {ParamGen._expand_vars(key, expand_func) : data[key] for key in data} + data = { + ParamGen._expand_vars(key, expand_func): data[key] for key in data + } # (2) Evaulate guards (if applicable) if ParamGen.is_guarded_dict(data): @@ -387,18 +389,17 @@ def _reduce_recursive(self, data, expand_func=None): # (3) Call _reduce_recursive for all branches of dict else: for key in data: - data[key] = self._reduce_recursive(data[key], expand_func) + data[key] = self._reduce_recursive(data[key], expand_func) - else: # data is not a dict, and so is a value. + else: # data is not a dict, and so is a value. # (4) Finally, process values by expanding vars and applying formulas if isinstance(data, str): data = ParamGen._expand_vars(data, expand_func) if is_formula(data): data = eval_formula(data.strip()[1:]) - - return data + return data def reduce(self, expand_func=None): """