def __init__(self, s):
        """Constructor.

        :param s: Expression string
        :type s: str
        :raises: ValueError if it doesn't match the syntax
        """
        # Match expression.
        m = self._expr.match(s)
        if m is None:
            raise ValueError("Bad syntax for delta '{}'".format(s))
        if m.span()[1] != len(s):
            p = m.span()[1]
            raise ValueError("Junk at end of delta '{}': {}".format(s, s[p:]))

        # Save a copy of orig.
        self._orig_expr = s

        # Initialize parsed values.
        self._sign = False
        self._dx, self._dy = 0, 0
        self._pct = False           # %change
        self._eq = False            # >=,<= instead of >, <

        # Set parsed values.
        d = m.groupdict()
        #print("@@ expr :: {}".format(d))
        if all((d[k] is None for k in ('X', 'Y', 'X2', 'Y2'))):
            # Change in sign only
            self._sign = True
            self._eq = d['eq'] is not None
        elif d['X'] is not None and d['Y'] is None:
            raise ValueError("Missing value for negative delta '{}'".format(s))
        else:
            if d['X2'] is not None:
                # Positive only
                self._dx = float(d['X2'])
                self._dy = None
            elif d['Y2'] is not None:
                # Negative only
                self._dx = None
                self._dy = -float(d['Y2'])
            else:
                # Both
                self._dy = -float(d['Y'])
                self._dx = float(d['X'] or d['Y'])
            self._eq = d['eq'] is not None
            self._pct = d['pct'] is not None
            #print("@@ dx,dy eq,pct = {},{}  {},{}".format(self._dx, self._dy, self._eq, self._pct))

        # Pre-calculate comparison function.
        if self._sign:
            self._cmp = self._cmp_sign
        elif self._pct:
            self._cmp = self._cmp_val_pct
        else:
            self._cmp = self._cmp_val_abs

        self._json_id = None
def __init__ ( self , s ) : m = self . _expr . match ( s ) if m is None : raise ValueError ( "Bad syntax for delta '{}'" . format ( s ) ) if m . span ( ) [ 1 ] != len ( s ) : p = m . span ( ) [ 1 ] raise ValueError ( "Junk at end of delta '{}': {}" . format ( s , s [ p : ] ) ) self . _orig_expr = s self . _sign = False self . _dx , self . _dy = 0 , 0 self . _pct = False self . _eq = False d = m . groupdict ( ) if all ( ( d [ k ] is None for k in ( 'X' , 'Y' , 'X2' , 'Y2' ) ) ) : self . _sign = True self . _eq = d [ 'eq' ] is not None elif d [ 'X' ] is not None and d [ 'Y' ] is None : raise ValueError ( "Missing value for negative delta '{}'" . format ( s ) ) else : if d [ 'X2' ] is not None : self . _dx = float ( d [ 'X2' ] ) self . _dy = None elif d [ 'Y2' ] is not None : self . _dx = None self . _dy = - float ( d [ 'Y2' ] ) else : self . _dy = - float ( d [ 'Y' ] ) self . _dx = float ( d [ 'X' ] or d [ 'Y' ] ) self . _eq = d [ 'eq' ] is not None self . _pct = d [ 'pct' ] is not None if self . _sign : self . _cmp = self . _cmp_sign elif self . _pct : self . _cmp = self . _cmp_val_pct else : self . _cmp = self . _cmp_val_abs self . _json_id = None
Constructor.

        :param s: Expression string
        :type s: str
        :raises: ValueError if it doesn't match the syntax