From bafc86d5831f357976854fbcc475f6e861ad7932 Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Sat, 21 Aug 2021 15:32:23 -0700 Subject: [PATCH] Add helpers to merge dictionaries and get keys deep inside a dictionary --- src/tests/test_helpers.py | 30 ++++++++++++++++++++++++++++++ src/utils/helpers.py | 19 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/tests/test_helpers.py diff --git a/src/tests/test_helpers.py b/src/tests/test_helpers.py new file mode 100644 index 00000000..6348d52c --- /dev/null +++ b/src/tests/test_helpers.py @@ -0,0 +1,30 @@ +from utils import helpers + +def test_get_from_null_dict(): + # null handling + assert helpers.get_from_dict(dict()) == dict() + assert helpers.get_from_dict(dict(), None) == None + + # key present in nested dictionary + # 1-level dictionary + assert helpers.get_from_dict({'a': 1, 'b': 2}, 'a') == 1 + assert helpers.get_from_dict({'a': 1, 'b': 2}, 'c') == None + + # 2-level dictionary + assert helpers.get_from_dict({'a': {'a_a': 1}, 'b': 2}, 'a') == {'a_a': 1} + assert helpers.get_from_dict({'a': {'a_a': 1}, 'b': 2}, 'a', 'a_a') == 1 + + # key not present in nested dictionary + # 2-level_dictionary + assert helpers.get_from_dict({'a': {'a_a': 1}, 'b': 2}, 'b', 'b_a') == None + + +def test_merge_dicts(): + # basic merge of dicts with non-overlapping keys + assert helpers.merge_dicts(priority_dict={'a': 1}, default_dict={'b': 2}) == {'a': 1, 'b': 2} + + # use default dict items when not present in priority dict + assert helpers.merge_dicts(priority_dict={}, default_dict={'b': 2}) == {'b': 2} + + # do not override existing key in priority_dict with default dict + assert helpers.merge_dicts(priority_dict={'a': 1}, default_dict={'a': 2}) == {'a': 1} diff --git a/src/utils/helpers.py b/src/utils/helpers.py index 64902835..2ed0bf36 100644 --- a/src/utils/helpers.py +++ b/src/utils/helpers.py @@ -7,3 +7,22 @@ def is_none_or_empty(item): def get_absolute_path(filepath): return str(pathlib.Path(filepath).expanduser().absolute()) + + +def get_from_dict(dictionary, *args): + '''null-aware get from a nested dictionary + Returns: dictionary[args[0]][args[1]]... or None if any keys missing''' + current = dictionary + for arg in args: + if not hasattr(current, '__iter__') or not arg in current: + return None + current = current[arg] + return current + + +def merge_dicts(priority_dict, default_dict): + merged_dict = priority_dict.copy() + for k, v in default_dict.items(): + if k not in priority_dict: + merged_dict[k] = default_dict[k] + return merged_dict