Source code for qp.dict_utils

"""This module implements tools to convert between distributions"""

import sys

import numpy as np


[docs]def get_val_or_default(in_dict, key): """Helper functions to return either an item in a dictionary or the default value of the dictionary Parameters ---------- in_dict : `dict` input dictionary key : `str` key to search for Returns ------- out : `dict` or `function` The requested item Notes ----- This will first try to return: in_dict[key] : i.e., the requested item. If that fails it will try in_dict[None] : i.e., the default for that dictionary. If that fails it will return None """ if key in in_dict: return in_dict[key] if None in in_dict: return in_dict[None] return None
[docs]def set_val_or_default(in_dict, key, val): """Helper functions to either get and item from or add an item to a dictionary and return that item Parameters ---------- in_dict : `dict` input dictionary key : `str` key to search for val : `dict` or `function` item to add to the dictionary Returns ------- out : `dict` or `function` The requested item Notes ----- This will first try to return: in_dict[key] : i.e., the requested item. If that fails it will try in_dict[None] : i.e., the default for that dictionary. If that fails it will return None """ if key in in_dict: return in_dict[key] in_dict[key] = val return val
[docs]def pretty_print(in_dict, prefixes, idx=0, stream=sys.stdout): """Print a level of the converstion dictionary in a human-readable format Parameters ---------- in_dict : `dict` input dictionary prefixs : `list` The prefixs to use at each level of the printing idx : `int` The level of the input dictionary we are currently printing stream : `stream` The stream to print to """ prefix = prefixes[idx] for key, val in in_dict.items(): if key is None: key_str = "default" else: key_str = key if isinstance(val, dict): # pragma: no cover stream.write("%s%s:\n" % (prefix, key_str)) pretty_print(val, prefixes, idx + 1, stream) else: stream.write("%s%s : %s\n" % (prefix, key_str, val))
[docs]def slice_dict(in_dict, subslice): """Create a new `dict` by taking a slice of of every array in a `dict` Parameters ---------- in_dict : `dict` The dictionary to conver subslice : `int` or `slice` Used to slice the arrays Returns ------- out_dict : `dict` The converted dicionary """ out_dict = {} for key, val in in_dict.items(): try: out_dict[key] = val[subslice] except (KeyError, TypeError): out_dict[key] = val return out_dict
[docs]def check_keys(in_dicts): """Check that the keys in all the in_dicts match Raises KeyError if one does not match. """ if not in_dicts: # pragma: no cover return master_keys = in_dicts[0].keys() for in_dict in in_dicts[1:]: if in_dict.keys() != master_keys: # pragma: no cover raise ValueError( "Keys to not match: %s != %s" % (in_dict.keys(), master_keys) )
[docs]def concatenate_dicts(in_dicts): """Create a new `dict` by concatenate each array in `in_dicts` Parameters ---------- in_dicts : `list` The dictionaries to stack Returns ------- out_dict : `dict` The stacked dicionary """ if not in_dicts: # pragma: no cover return {} check_keys(in_dicts) out_dict = {key: None for key in in_dicts[0].keys()} for key in out_dict.keys(): out_dict[key] = np.concatenate([in_dict[key] for in_dict in in_dicts]) return out_dict
[docs]def check_array_shapes(in_dict, npdf): """Check that all the arrays in in_dict match the number of pdfs Raises ValueError if one does not match. """ if in_dict is None: return for key, val in in_dict.items(): if np.size(val) == 1 and npdf == 1: # pragma: no cover continue if np.shape(val)[0] != npdf: # pragma: no cover raise ValueError( "First dimension of array %s does not match npdf: %i != %i" % (key, np.shape(val)[0], npdf) )
[docs]def compare_two_dicts(d1, d2): """Check that all the items in d1 and d2 match Returns ------- match : `bool` True if they all match, False otherwise """ if d1.keys() != d2.keys(): # pragma: no cover return False for k, v in d1.items(): vv = d2[k] try: if v != vv: # pragma: no cover return False except ValueError: if not np.allclose(v, vv): # pragma: no cover return False return True
[docs]def compare_dicts(in_dicts): """Check that all the dicts in in_dicts match Returns ------- match : `bool` True if they all match, False otherwise """ if not in_dicts: # pragma: no cover return True first_dict = in_dicts[0] for in_dict in in_dicts[1:]: if not compare_two_dicts(first_dict, in_dict): # pragma: no cover return False return True