Source code for lsst.sims.maf.utils.outputUtils

from __future__ import print_function
from builtins import map
from builtins import str
from builtins import range
import sys
import numpy as np

__all__ = ['nameSanitize', 'printDict', 'printSimpleDict']


[docs]def nameSanitize(inString): """ Convert a string to a more file name (and web) friendly format. Parameters ---------- inString : str The input string to be sanitized. Typically these are combinations of metric names and metadata. Returns ------- str The string after removal/replacement of non-filename friendly characters. """ # Replace <, > and = signs. outString = inString.replace('>', 'gt').replace('<', 'lt').replace('=', 'eq') # Remove single-spaces, strip '.'s and ','s outString = outString.replace(' ', '_').replace('.', '_').replace(',', '') # and remove / and \ outString = outString.replace('/', '_').replace('\\', '_') # and remove parentheses outString = outString.replace('(', '').replace(')', '') # Remove ':' and ';" outString = outString.replace(':', '_').replace(';', '_') # Replace '%' and # outString = outString.replace('%', '_').replace('#', '_') # Remove '__' while '__' in outString: outString = outString.replace('__', '_') return outString
def _myformat(args, delimiter=' '): # Generic line formatter to let you specify delimiter between text fields. writestring = '' # Wrap in a list if something like an int gets passed in if not hasattr(args, '__iter__'): args = [args] for a in args: if isinstance(a, list): if len(a) > 1: ap = ','.join(map(str, a)) else: ap = ''.join(map(str, a)) writestring += '%s%s' % (ap, delimiter) else: writestring += '%s%s' % (a, delimiter) return writestring def _myformatdict(adict, delimiter=' '): # Generic line formatter used for dictionaries. writestring = '' for k, v in adict.items(): if isinstance(v, list): if len(v) > 1: vp = ','.join(map(str, v)) else: vp = ''.join(map(str, v)) writestring += '%s:%s%s' % (k, vp, delimiter) else: writestring += '%s:%s%s' % (k, v, delimiter) return writestring
[docs]def printDict(content, label, filehandle=None, delimiter=' ', _level=0): """ Print dictionaries (and/or nested dictionaries) nicely. Can also print other simpler items (such as numpy ndarray) nicely too. This is used to print the config files. Parameters ---------- content : dict The content to pretty print. label : str A header for this level of the dictionary. filename : file Output destination. If None, prints to stdout. delimiter : str User specified delimiter between fields. _level : int Internal use (controls level of indent). """ # Get set up with basic file output information. if filehandle is None: filehandle = sys.stdout # And set character to use to indent sets of parameters related to a single dictionary. baseindent = '%s' % (delimiter) indent = '' for i in range(_level-1): indent += '%s' % (baseindent) # Print data (this is also the termination of the recursion if given nested dictionaries). if not isinstance(content, dict): if isinstance(content, str) or isinstance(content, float) or isinstance(content, int): print('%s%s%s%s' % (indent, label, delimiter, str(content)), file=filehandle) else: if isinstance(content, np.ndarray): if content.dtype.names is not None: print('%s%s%s' % (indent, delimiter, label), file=filehandle) for element in content: print('%s%s%s%s%s' % (indent, delimiter, indent, delimiter, _myformat(element)), file=filehandle) else: print('%s%s%s%s' % (indent, label, delimiter, _myformat(content)), file=filehandle) else: print('%s%s%s%s' % (indent, label, delimiter, _myformat(content)), file=filehandle) return # Allow user to specify print order of (some or all) items in order via 'keyorder'. # 'keyorder' is list stored in the dictionary. if 'keyorder' in content: orderkeys = content['keyorder'] # Check keys in 'keyorder' are actually present in dictionary : remove those which aren't. missingkeys = set(orderkeys).difference(set(content.keys())) for m in missingkeys: orderkeys.remove(m) otherkeys = sorted(list(set(content.keys()).difference(set(orderkeys)))) keys = orderkeys + otherkeys keys.remove('keyorder') else: keys = sorted(content.keys()) # Print data from dictionary. print('%s%s%s:' % (indent, delimiter, label), file=filehandle) _level += 2 for k in keys: printDict(content[k], k, filehandle, delimiter, _level) _level -= 2
[docs]def printSimpleDict(topdict, subkeyorder, filehandle=None, delimiter=' '): """ Print a simple one-level nested dictionary nicely across the screen, with one line per top-level key and all sub-level keys aligned. Parameters ---------- topdict : dict The dictionary to pretty print subkeyorder : list of strings The order to print the values of the dictionary. filehandle : file File output object, if None then uses stdout. delimiter : str User specified delimiter between fields. """ # Get set up with basic file output information. if filehandle is None: filehandle = sys.stdout # Get all sub-level keys. subkeys = [] for key in topdict: subkeys += list(topdict[key].keys()) subkeys = list(set(subkeys)) # Align subkeys with 'subkeyorder' and then alphabetize any remaining. missingkeys = set(subkeyorder).difference(set(subkeys)) for m in missingkeys: subkeyorder.remove(m) otherkeys = sorted(list(set(subkeys).difference(set(subkeyorder)))) subkeys = subkeyorder + otherkeys # Print header. writestring = '#' for s in subkeys: writestring += '%s%s' % (s, delimiter) print(writestring, file=filehandle) # Now go through and print. for k in topdict: writestring = '' for s in subkeys: if s in topdict[k]: if isinstance(topdict[k][s], str) or isinstance(topdict[k][s], float) or isinstance(topdict[k][s], int): writestring += '%s%s' % (topdict[k][s], delimiter) elif isinstance(topdict[k][s], dict): writestring += '%s%s' % (_myformatdict(topdict[k][s], delimiter=delimiter), delimiter) else: writestring += '%s%s' % (_myformat(topdict[k][s]), delimiter) else: writestring += '%s' % (delimiter) print(writestring, file=filehandle)