Source code for ccpn.core.lib.CcpnSorting

""" Ccpn-specific variant of functions for sorting and comparison."""

#=========================================================================================
# Licence, Reference and Credits
#=========================================================================================
__copyright__ = "Copyright (C) CCPN project (http://www.ccpn.ac.uk) 2014 - 2019"
__credits__ = ("Ed Brooksbank, Luca Mureddu, Timothy J Ragan & Geerten W Vuister")
__licence__ = ("CCPN licence. See http://www.ccpn.ac.uk/v3-software/downloads/license")
__reference__ = ("Skinner, S.P., Fogh, R.H., Boucher, W., Ragan, T.J., Mureddu, L.G., & Vuister, G.W.",
                 "CcpNmr AnalysisAssign: a flexible platform for integrated NMR analysis",
                 "J.Biomol.Nmr (2016), 66, 111-124, http://doi.org/10.1007/s10858-016-0060-y")
#=========================================================================================
# Last code modification
#=========================================================================================
__modifiedBy__ = "$modifiedBy: CCPN $"
__dateModified__ = "$dateModified: 2017-07-07 16:32:31 +0100 (Fri, July 07, 2017) $"
__version__ = "$Revision: 3.0.0 $"
#=========================================================================================
# Created
#=========================================================================================
__author__ = "$Author: CCPN $"
__date__ = "$Date: 2017-04-07 10:28:41 +0000 (Fri, April 07, 2017) $"
#=========================================================================================
# Start of code
#=========================================================================================

import re
from ccpn.util import Sorting


SPLITONDOTS = re.compile("([.])")

_keyCache = {}


#
[docs]def stringSortKey(key: str) -> tuple: """Sort key for strings. Usage: sorted(aList, key=stringSortKey) or aList.sort(key=stringSortKey) Custom CCPN version of stringSortKey that sorts Pids on their individual components. Advanced: Splits on embedded dots before further processing, and Returns an alternating tuple of (possibly empty) strings interspersed with (float,string) tuples, where the float is the converted value of the substring. First and last element are always strings. If the entire string evaluates to a float, the result is ('', '(floatVal, stringVal), '') Otherwise the numeric tuples are (intVal, subStringVal). Substrings recognised as integers are an optional series of ' ', an optional sign, and a series of digits - or REGEX '[ ]*[+-]?\d+' For this type the key tuple is extended by (0,''), # so that end-of-key sorts as 0 rather thn coming first. Example of sorting order ['', 'NaN', '-1', '-1A', '0.0', '1', '2', '15', '3.2e12', 'Inf', 'Ahh', 'b', 'b2', 'b12', 'bb', 'ciao'] """ keyEnd = ((0, ''), '') global _keyCache result = _keyCache.get(key) if result is None: tt = Sorting._floatStringKey(key) if tt: # Read as floating point number if possible result = (tt,) elif '.' in key: # Otherwise treat dot ('.') as a field separator ll = [Sorting._numericSplitString(x) for x in SPLITONDOTS.split(key) if x != ''] # result = tuple(x if x[-1] else x + keyEnd for x in ll) result = tuple(x + keyEnd for x in ll) else: # Simple string result = Sorting._numericSplitString(key) # if len(result) > 1 and result[-1] == '': if len(result) > 1: # String ended with a numeric field. Add keyEnd so that this sorts as 0 # against keys where the next field is also numeric result += keyEnd result = (result,) # _keyCache[key] = result # return result
def _ccpnOrderedKey(key): """Special case sorting key for CCPN - groups CCPN AbstractWrapperObjects together before sorting by class name""" # import here to avoid circular imports from ccpn.core._implementation.AbstractWrapperObject import AbstractWrapperObject cls = key.__class__ ordering = 0 if isinstance(key, AbstractWrapperObject): ordering = -1 # return (ordering, cls.__name__, id(cls), key)
[docs]def universalSortKey(key): """Custom universalSortKey, used to sort a list of mixed-type Python objects. Usage: sorted(aList, key=universalSortKey) or aList.sort(key=universalSortKey) Uses the local stringSortKey variant for strings and CCPN WrapperObjects sorted together""" return Sorting.universalSortKey(key, _stringOrderingHook=stringSortKey, _orderedKeyHook=_ccpnOrderedKey)