From 8555ecad33e7d0fe7f49f1d7f9a95bcbbea20845 Mon Sep 17 00:00:00 2001 From: David Hendriks <davidhendriks93@gmail.com> Date: Wed, 8 Sep 2021 15:24:37 +0100 Subject: [PATCH] Fixed issue with the autovivication --- binarycpython/tests/test_grid.py | 6 ++---- binarycpython/utils/functions.py | 31 +++++++++++++++++++------------ 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/binarycpython/tests/test_grid.py b/binarycpython/tests/test_grid.py index 7c248f803..cb3129423 100644 --- a/binarycpython/tests/test_grid.py +++ b/binarycpython/tests/test_grid.py @@ -3,7 +3,6 @@ Test cases for the grid Tasks: TODO: write tests for load_from_sourcefile - TODO: Set the temp_dir to grid_tests subdir. Should use that as an argument for the temp_dir() function """ import os @@ -1093,7 +1092,7 @@ class test_resultdict(unittest.TestCase): example_pop.set( max_evolution_time=15000, # bse_options # grid_options - amt_cores=2, + amt_cores=3, tmp_dir=TMP_DIR, # Custom options @@ -1142,10 +1141,9 @@ class test_resultdict(unittest.TestCase): ) # Check if the total count matches - self.assertAlmostEqual( + self.assertEqual( grid_count, result_dict_count, - places=12, msg="Total count from grid {} and from result dict {} are not equal".format(grid_count, result_dict_count) ) diff --git a/binarycpython/utils/functions.py b/binarycpython/utils/functions.py index 88e994cfa..0138fc326 100644 --- a/binarycpython/utils/functions.py +++ b/binarycpython/utils/functions.py @@ -41,9 +41,18 @@ import py_rinterpolate ######################################################## class AutoVivificationDict(dict): """ - Implementation of perl's autovivification feature. + Implementation of perl's autovivification feature, by overriding the + get item and the __iadd__ operator (https://docs.python.org/3/reference/datamodel.html?highlight=iadd#object.__iadd__) + + This allows to set values within a subdict that might not exist yet: + + Example: + newdict = {} + newdict['example']['mass'] += 10 + print(newdict) + >>> {'example': {'mass': 10}} """ - + def __getitem__(self, item): try: return dict.__getitem__(self, item) @@ -1585,7 +1594,7 @@ def merge_dicts(dict_1: dict, dict_2: dict) -> dict: """ # Set up new dict - new_dict = OrderedDict() # TODO: check if this still works + new_dict = OrderedDict() # TODO: check if this still necessary # keys_1 = dict_1.keys() @@ -1620,19 +1629,17 @@ def merge_dicts(dict_1: dict, dict_2: dict) -> dict: # Go over the common keys: for key in overlapping_keys: - # See whether the types are actually the same + # If they keys are not the same, it depends on their type whether we still deal with them at all, or just raise an error if not type(dict_1[key]) is type(dict_2[key]): - # Exceptions: - if (type(dict_1[key]) in [int, float, np.float64]) and ( - type(dict_2[key]) in [int, float, np.float64] - ): + # Exceptions: numbers can be added + if isinstance(dict_1[key], (int, float, np.float64)) and isinstance(dict_2[key], (int, float, np.float64)): new_dict[key] = dict_1[key] + dict_2[key] - # Exceptions: - elif (type(dict_1[key]) in [dict, OrderedDict]) and ( - type(dict_2[key]) in [dict, OrderedDict] - ): + + # Exceptions: versions of dicts can be merged + elif isinstance(dict_1[key], (dict, OrderedDict, type(AutoVivificationDict))) and isinstance(dict_2[key], (dict, OrderedDict, type(AutoVivificationDict))): new_dict[key] = merge_dicts(dict_1[key], dict_2[key]) + # If the above cases have not dealt with it, then we should raise an error else: print( "Error key: {} value: {} type: {} and key: {} value: {} type: {} are not of the same type and cannot be merged".format( -- GitLab