Coverage for tcvx21/dict_methods_m.py: 97%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

36 statements  

1""" 

2Methods for simplifying interaction with nested dictionaries 

3""" 

4import numpy as np 

5 

6 

7def summarise_tree_dict(tree: dict, indentation='-> ', show_values: bool = False): 

8 """Prints out the nested keys of a dictionary, recursively""" 

9 

10 indentation = ' ' + indentation 

11 values = {} 

12 

13 for key, value in tree.items(): 

14 

15 if isinstance(value, dict): 

16 print(f"{indentation}{key}") 

17 summarise_tree_dict(value, indentation=indentation, show_values=show_values) 

18 else: 

19 values[key] = value if not isinstance(value, np.ndarray) else value.shape 

20 

21 if values and show_values: 

22 print(indentation + ' '.join( 

23 [f'{key}: {value}' for key, value in values.items()])) 

24 

25 

26def recursive_assert_dictionaries_equal(dict_a, dict_b): 

27 assert dict_a.keys() == dict_b.keys() 

28 

29 for key, val in dict_a.items(): 

30 

31 try: 

32 if isinstance(val, dict): 

33 recursive_assert_dictionaries_equal(val, dict_b[key]) 

34 elif len(val) == 0: 

35 assert len(dict_b[key]) == 0 

36 elif isinstance(val, np.ndarray): 

37 assert np.allclose(val, dict_b[key]) 

38 else: 

39 assert val == dict_b[key] 

40 except TypeError: 

41 # Fallback in case object has no len 

42 assert val == dict_b[key] 

43 except AssertionError as e: 

44 print(f"key = {key}, left = {val} ({type(val)}), right = {dict_b[key]} ({type(dict_b[key])})") 

45 raise e from None 

46 

47# def collapse_single_entries_in_dict(tree: dict): 

48# """Recursively collapses single-keyed entries of a nested dictionary""" 

49 

50# for key in tree.keys(): 

51 

52# if isinstance(tree[key], dict): 

53# if len(tree[key].keys()) == 1: 

54# sub_key = list(tree[key].keys())[0] 

55# print(f"Collapsing {key}:{sub_key} to {key}") 

56 

57# tree[key] = tree[key][sub_key] 

58 

59# if isinstance(tree[key], dict): 

60# tree[key] = collapse_single_entries_in_dict(tree[key]) 

61 

62# return tree 

63 

64 

65def recursive_rename_keys(old_dict: dict, old_to_new_map: dict): 

66 """ 

67 Given a nested dictionary 'old_dict', recursively update all keys according to old_to_new_map 

68 """ 

69 

70 if not isinstance(old_dict, dict): 

71 return old_dict 

72 

73 new_dict = {} 

74 for key, value in old_dict.items(): 

75 if key in old_to_new_map: 

76 new_dict[old_to_new_map[key]] = recursive_rename_keys(value, old_to_new_map) 

77 else: 

78 new_dict[key] = recursive_rename_keys(value, old_to_new_map) 

79 

80 return new_dict