
    A6iU                     z   d Z ddlZddlmZmZmZ ddlmZmZ ddlm	Z	m
Z
 ddlmZmZ ddlmZmZmZmZ dd	lmZmZ d
 Zd Zd"dZd#dZd$dZd Z G d de      Z G d de      Z G d de      Z G d de      Z  G d de      Z! G d de      Z" G d de      Z# G d de      Z$ G d  d!e      Z% e%       Z&y)%z
http://grouper.ieee.org/groups/1788/PositionPapers/ARITHYY.pdf

http://grouper.ieee.org/groups/1788/PositionPapers/overlapping.pdf

https://en.wikipedia.org/wiki/Interval_(mathematics)
    N)datedatetime	timedelta)DecimalInvalidOperation)ceilfloor)infis_infinite   )IllegalArgumentIntervalExceptionRangeBoundsExceptionValueCoercionException)IntervalParserIntervalStringParserc                 8    t        | t        t        t        f      S N)
isinstancefloatintr   )numbers    U/home/azureuser/techstart-app/venv/lib/python3.12/site-packages/intervals/interval.py	is_numberr      s    fuc7344    c                     | dkD  r t        t        t        |       dz               S t        t        t        |       dz
              S )az  Round values as in Python 2, for Python 3 compatibility.

    All x.5 values are rounded away from zero.

    In Python 3, this has changed to avoid bias: when x is even,
    rounding is towards zero, when x is odd, rounding is away
    from zero. Thus, in Python 3, round(2.5) results in 2,
    round(3.5) is 4.

    Python 3 also returns an int; Python 2 returns a float.
    r   g      ?)r   r	   r   )values    r   py2roundr      s=     qyU5<+,--T%,s*+,,r   c                     | j                   s|r| j                  | j                  z   dfS |s'| j                   r| j                  | j                  z
  dfS | j                  | j                   fS NTF)	lower_inclowerstepintervalincs     r   canonicalize_lowerr'   0   ]    #~~-t33X''~~-u44~~x1111r   c                     | j                   s|r| j                  | j                  z
  dfS |s'| j                   r| j                  | j                  z   dfS | j                  | j                   fS r    )	upper_incupperr#   r$   s     r   canonicalize_upperr,   9   r(   r   c                     | j                   st        d      | j                  r| S t        | |      \  }}t	        | |      \  }}| j                  ||g||      S )zM
    Convert equivalent discrete intervals to different representations.
    z)Only discrete ranges can be canonicalizedr!   r*   )discrete	TypeErroremptyr'   r,   	__class__)r%   r!   r*   r"   r+   s        r   canonicalizer3   B   sl     CDD~~)(I>E9)(I>E9	   r   c                       fd}|S )Nc                    t        |t              sNt        |t              s>t        || j                        s(t        |t        |             s|t        k(  s
|t         k(  r	 | t        |       |      } | |      S 	  t        |       | j                  |            } | |      S # t
        $ r	 t        cY S w xY w# t        t        t        f$ r Y 4w xY wr   )
r   listtupletyper
   r   NotImplemented
ValueErrorr0   OverflowError)selfargfuncs     r   wrapperz coerce_interval.<locals>.wrapperW   s    sD!sE"sDII&sDJ'3J##+&?$$t*S/CD#&	$t*TYYs^,C D# % &%%& I}5 		s$   !B' > B< 'B98B9<CC )r>   r?   s   ` r   coerce_intervalrA   V   s    & Nr   c                      e Zd ZdZdZ e       Z	 	 	 d6dZed        Z	ed        Z
ed        Zed        Zed        Zed        Zed	        Zed
        Zed        Zed        Zd Zd Zd Zd Zed        Zej2                  d        Zed        Zej2                  d        Zd Zed        Zed        Zd Zd Ze d        Z!d Z"d Z#e d        Z$e d        Z%e d        Z&e d         Z'e d!        Z(ed"        Z)ed#        Z*ed$        Z+ed%        Z,ed&        Z-d' Z.d( Z/ed)        Z0d* Z1ed+        Z2e d,        Z3e3Z4e d-        Z5e d.        Z6e d/        Z7e d0        Z8e d1        Z9e d2        Z:d3 Z;d4 Z<d5 Z=y)7AbstractIntervalNc                    t        |t              rt        d      ||| _        | j	                  |||      \  | _        | _        | _        | _        | j
                  | j                  kD  r t        | j
                  | j                        | j
                  | j                  k(  r%| j                  s| j                  st        d      yyy)a  
        Parse given args and assign lower and upper bound for this number
        range.

        1. Comma separated string argument::

            >>> range = IntInterval.from_string('[23, 45]')
            >>> range.lower
            23
            >>> range.upper
            45

            >>> range = IntInterval.from_string('(23, 45]')
            >>> range.lower_inc
            False

            >>> range = IntInterval.from_string('(23, 45)')
            >>> range.lower_inc
            False
            >>> range.upper_inc
            False

        2. Lists and tuples as an argument::

            >>> range = IntInterval([23, 45])
            >>> range.lower
            23
            >>> range.upper
            45
            >>> range.is_closed
            True

            >>> range = IntInterval((23, 45))
            >>> range.lower
            23
            >>> range.is_closed
            False

        3. Integer argument::

            >>> range = IntInterval(34)
            >>> range.lower == range.upper == 34
            True

        4. Object argument::

            >>> range = IntInterval(IntInterval((20, 30)))
            >>> range.lower
            20
            >>> range.upper
            30

        z|First argument should be a list or tuple. If you wish to initialize an interval from string, use from_string factory method.NzEThe bounds may be equal only if at least one of the bounds is closed.)r   strr0   r#   parserr"   r+   r!   r*   r   r   )r<   boundsr!   r*   r#   s        r   __init__zAbstractInterval.__init__r   s    x fc"  DIKK	95 	?
DJ ::

"&



 
 JJ$**$!    %r   c                      | ||gfddd|S NFr.   r@   clslower_boundupper_boundkwargss       r   openzAbstractInterval.open   s,    +&

 	
 	
r   c                      | ||gfddd|S )NTr.   r@   rK   s       r   closedzAbstractInterval.closed   s,    +&

 	
 	
r   c                      | ||gfddd|S NFTr.   r@   rK   s       r   open_closedzAbstractInterval.open_closed   s,    +&

 	
 	
r   c                      | ||gfddd|S NTFr.   r@   rK   s       r   closed_openzAbstractInterval.closed_open   s,    +&

 	
 	
r   c                 &     | |t         gfddd|S rJ   r
   rL   rM   rO   s      r   greater_thanzAbstractInterval.greater_than   s,    #

 	
 	
r   c                 &     | |t         gfddd|S rW   rZ   r[   s      r   at_leastzAbstractInterval.at_least   s,    #

 	
 	
r   c                 (     | t          |gfddd|S rJ   rZ   rL   rN   rO   s      r   	less_thanzAbstractInterval.less_than   s.    T;

 	
 	
r   c                 (     | t          |gfddd|S rT   rZ   r`   s      r   at_mostzAbstractInterval.at_most	  s.    T;

 	
 	
r   c                 0     | t          t         gfddd|S rJ   rZ   )rL   rO   s     r   allzAbstractInterval.all  s-    T3K

 	
 	
r   c                 @     | t               j                  |      i |S r   )r   parse_string)rL   bounds_stringrO   s      r   from_stringzAbstractInterval.from_string  s(    !#00?

 	
r   c                     |j                   | _         |j                  | _        |j                  | _        |j                  | _        |j                  | _        y r   )r!   r*   r"   r+   r8   )r<   r%   s     r   	copy_argszAbstractInterval.copy_args"  s=    !++!++^^
^^
MM	r   c                     ||dk(  ry t        |      r|S t        || j                        r|S t        |t              r| j	                  |      S | j                  |      S )N )r   r   r8   rE   coerce_string
coerce_objr<   r   s     r   coerce_valuezAbstractInterval.coerce_value)  sZ    =ERKLtyy)Ls#%%e,,??5))r   c                 `    	 | j                  |      S # t        t        f$ r t               w xY wr   r8   r:   r0   r   rp   s     r   rn   zAbstractInterval.coerce_string5  s3    	+99U##I& 	+(**	+    -c                 `    	 | j                  |      S # t        t        f$ r t               w xY wr   rs   r<   objs     r   ro   zAbstractInterval.coerce_obj;  s2    	+99S>!I& 	+(**	+rt   c                     | j                   S r   )_lowerr<   s    r   r"   zAbstractInterval.lowerA      {{r   c                 p    | j                  |      }|t         | _        y | j                  |      | _        y r   )rq   r
   ry   round_value_by_steprp   s     r   r"   zAbstractInterval.lowerE  s2    !!%(=$DK2259DKr   c                     | j                   S r   )_upperrz   s    r   r+   zAbstractInterval.upperM  r{   r   c                 n    | j                  |      }|t        | _        y | j                  |      | _        y r   )rq   r
   r   r}   rp   s     r   r+   zAbstractInterval.upperQ  s0    !!%(=DK2259DKr   c                     |S r   r@   rp   s     r   r}   z$AbstractInterval.round_value_by_stepY  s    r   c                 :    | j                    xr | j                   S )a0  
        Return whether or not this object is an open interval.

        Examples::

            >>> range = Interval.from_string('(23, 45)')
            >>> range.is_open
            True

            >>> range = Interval.from_string('[23, 45]')
            >>> range.is_open
            False

        r.   rz   s    r   is_openzAbstractInterval.is_open\  s      >>!8$..&88r   c                 6    | j                   xr | j                  S )a5  
        Return whether or not this object is a closed interval.

        Examples::

            >>> range = Interval.from_string('(23, 45)')
            >>> range.is_closed
            False

            >>> range = Interval.from_string('[23, 45]')
            >>> range.is_closed
            True

        r.   rz   s    r   	is_closedzAbstractInterval.is_closedn  s      ~~0$..0r   c                    | j                   rdndt        | j                        st        | j                        nddt        | j                        sdt        | j                        z   nd| j
                  rdS dS )N[(rm   , ]))r!   r   r"   rE   r+   r*   rz   s    r   __str__zAbstractInterval.__str__  ss    >>Cs*#.tzz#:C

OB)4TZZ)@C#djj/!bH>>C*	
 	
 (+*	
 	
r   c                    | j                   |j                   k(  xrj | j                  |j                  k(  xrO | j                  |j                  k(  xr4 | j                  |j                  k(  xr | j                  |j                  k(  S r   )r"   r+   r!   r*   r8   r<   others     r   equalszAbstractInterval.equals  so    JJ%++% $JJ%++%$NNeoo-$ NNeoo-$ II#	
r   c                     	 | j                   r#t        |       j                  t        |            S | j                  |      S # t        $ r	 t        cY S w xY wr   )r/   r3   r   AttributeErrorr9   r   s     r   __eq__zAbstractInterval.__eq__  sM    	"}}#D)00e1DEE;;u%% 	"!!	"s   .A A AAc                     | j                   | j                  | j                  | j                  | j                  fj                         S r   )r+   r"   r*   r!   r8   __hash__rz   s    r   r   zAbstractInterval.__hash__  s8    JJJJNNNNII
 (*	r   c                     | |k(   S r   r@   r   s     r   __ne__zAbstractInterval.__ne__  s    EM""r   c                 j    | j                   |j                   kD  xr | j                  |j                  kD  S r   r"   r+   r   s     r   __gt__zAbstractInterval.__gt__  '    zzEKK'DDJJ,DDr   c                 j    | j                   |j                   k  xr | j                  |j                  k  S r   r   r   s     r   __lt__zAbstractInterval.__lt__  r   r   c                     | |k(  xs | |kD  S r   r@   r   s     r   __ge__zAbstractInterval.__ge__      u},u,r   c                     | |k(  xs | |k  S r   r@   r   s     r   __le__zAbstractInterval.__le__  r   r   c                    | j                   s| j                   s|j                   st        j                  nt        j                  }| j                  s| j                  s|j                  st        j
                  nt        j                  } || j                  |j                        xr  || j                  |j                        S r   )	r!   operatorleltr*   gegtr"   r+   )r<   r   lower_opupper_ops       r   __contains__zAbstractInterval.__contains__  s     ~~dnnU__ KK 	 ~~dnnU__ KK 	 TZZ- .TZZ-	
r   c                     | j                   duS )zB
        Return whether or not this interval is discrete.
        N)r#   rz   s    r   r/   zAbstractInterval.discrete  s    
 yy$$r   c                     | j                   r3| sy| j                  r| j                  st        | dd      j                  S t        | j                  | j                  z
        S )Nr   Tr.   )r/   r!   r*   r3   lengthabsr+   r"   rz   s    r   r   zAbstractInterval.length  sI    ==>>#DDDIPPP4::

*++r   c                 d    | j                   t        k(  rt        S t        | j                         dz  S N   )r   r
   r   rz   s    r   radiuszAbstractInterval.radius  s'    ;;#JT[[!A%%r   c                 4    | j                   | j                  k(  S )zn
        An interval is considered degenerate if it only contains one item or
        if it is empty.
        )r+   r"   rz   s    r   
degeneratezAbstractInterval.degenerate  s     zzTZZ''r   c                 $   | j                   rO| j                  sC| j                  | j                  z
  | j                  k(  xr | j
                  xs | j                   S | j                  | j                  k(  xr | j                  xr | j
                   S r   )r/   r   r+   r"   r#   r*   r!   rz   s    r   r1   zAbstractInterval.empty  st    ==

TZZ'4994 ;94>>:
 JJ$**$ 8^^67	
r   c                     | j                    S r   r1   rz   s    r   __bool__zAbstractInterval.__bool__      ::~r   c                     | j                    S r   r   rz   s    r   __nonzero__zAbstractInterval.__nonzero__  r   r   c                 L    t        | j                  | j                  z         dz  S r   )r   r"   r+   rz   s    r   centrezAbstractInterval.centre  s    djj4::-/!33r   c                 L    | j                   j                  dt        |       dS )Nr   r   )r2   __name__rE   rz   s    r   __repr__zAbstractInterval.__repr__  s    >>22CI>>r   c                 f   | j                   st        d      t        | dd      }|j                  |j                  k7  r`t        |j                        st        |j                        nddt        |j                        sdt        |j                        z   S dS t        |j                        S )Nz/Only discrete intervals have hyphenized format.Trm   z -r   )r/   r0   r3   r"   r+   r   rE   )r<   cs     r   
hyphenizedzAbstractInterval.hyphenized  s    }}MNNtT*77agg$/$8AGGb@*5agg*>c!''l"F DFF  177|r   c                     | j                  | j                  |j                  z   | j                  |j                  z   g| |k  r| j                  n|j                  | |kD  r| j                        S |j                        S )z2
        [a, b] + [c, d] = [a + c, b + d]
        r.   )r2   r"   r+   r!   r*   r   s     r   __add__zAbstractInterval.__add__  sz    
 ~~

U[[(

U[[( )-udnn%//(,udnn  
 	
 ;@//  
 	
r   c                     | j                  | j                  |j                  z
  | j                  |j                  z
  g      S )z]
        Define the substraction operator.

        [a, b] - [c, d] = [a - d, b - c]
        r2   r"   r+   r   s     r   __sub__zAbstractInterval.__sub__  s:     ~~JJ$JJ$
  	r   c                    | j                  t        | j                  |j                        t        | j                  |j                        g| |k  r| j                  n|j                  | |kD  r| j
                        S |j
                        S )zw
        Return the greatest lower bound for given intervals.

        :param other: AbstractInterval instance
        r.   )r2   minr"   r+   r!   r*   r   s     r   glbzAbstractInterval.glb(  ~     ~~DJJ,DJJ, )-udnn%//(,udnn  
 	
 ;@//  
 	
r   c                    | j                  t        | j                  |j                        t        | j                  |j                        g| |k  r| j                  n|j                  | |kD  r| j
                        S |j
                        S )zt
        Return the least upper bound for given intervals.

        :param other: AbstractInterval instance
        r.   )r2   maxr"   r+   r!   r*   r   s     r   lubzAbstractInterval.lub8  r   r   c                     | |z  S )z
        Return the infimum of given intervals. This is the same as
        intersection.

        :param other: AbstractInterval instance
        r@   r   s     r   r
   zAbstractInterval.infH  s     e|r   c                     | |z  S )z
        Return the supremum of given intervals. This is the same as union.

        :param other: AbstractInterval instance
        r@   r   s     r   supzAbstractInterval.supR  s     e|r   c                     | j                  |j                  | j                  z
  |j                  | j                  z
  g      S r   r   r   s     r   __rsub__zAbstractInterval.__rsub__[  s8    ~~KK$**$KK$**$
  	r   c                 ~   | j                  |      st        d      t        | j                  |j                        }t	        | j
                  |j
                        }| j                  |j                  k  r|j                  }n@| j                  |j                  kD  r| j                  }n| j                  xr |j                  }| j
                  |j
                  kD  r|j                  }n@| j
                  |j
                  k  r| j                  }n| j                  xr |j                  }| j                  ||g||      S )z2
        Define the intersection operator
        z7Intersection is only supported for connected intervals.r.   )	is_connectedr   r   r"   r   r+   r!   r*   r2   r<   r   r"   r+   r!   r*   s         r   __and__zAbstractInterval.__and__b  s       '!I  DJJ,DJJ,::#IZZ%++%I:5??I::#IZZ%++%I:5??I~~EN  
 	
r   c                 ~   | j                  |      st        d      t        | j                  |j                        }t	        | j
                  |j
                        }| j                  |j                  k  r| j                  }n@| j                  |j                  kD  r|j                  }n| j                  xs |j                  }| j
                  |j
                  kD  r| j                  }n@| j
                  |j
                  k  r|j                  }n| j                  xs |j                  }| j                  ||g||      S )z+
        Define the union operator
        zUnion is not continuous.r.   )	r   r   r   r"   r   r+   r!   r*   r2   r   s         r   __or__zAbstractInterval.__or__  s       '!"<==DJJ,DJJ,::#IZZ%++%I9%//I::#IZZ%++%I9%//I~~EN  
 	
r   c                 F   | j                   |j                  kD  xr |j                   | j                  kD  xsl | j                   |j                  k(  xr | j                  xs |j                  xs5 | j                  |j                   k(  xr | j                  xs |j                  S )a  
        Returns ``True`` if there exists a (possibly empty) range which is
        enclosed by both this range and other.

        Examples:

        * [1, 3] and [5, 7] are not connected
        * [5, 7] and [1, 3] are not connected
        * [2, 4) and [3, 5) are connected, because both enclose [3, 4)
        * [1, 3) and [3, 5) are connected, because both enclose the empty range
          [3, 3)
        * [1, 3) and (3, 5) are not connected
        )r+   r"   r*   r!   r   s     r   r   zAbstractInterval.is_connected  s{     zzEKK'DEKK$**,D 
JJ%++%M4>>+LU__
 JJ%++%M4>>+LU__	
r   NNN)>r   
__module____qualname__r#   r8   r   rF   rH   classmethodrP   rR   rU   rX   r\   r^   ra   rc   re   ri   rk   rq   rn   ro   propertyr"   setterr+   r}   r   r   r   r   rA   r   r   r   r   r   r   r   r   r/   r   r   r   r1   r   r   r   r   r   r   __radd__r   r   r   r
   r   r   r   r   r   r@   r   r   rC   rC   m   sS   DDF
 Vp 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
"
*++   \\: :   \\: : 9 9" 1 1"

 " "# E E E E - - - - 
 
" % % , , & &
 ( ( 	
 	
 4 4? 
 
 
 
 H	 	 
 
 
 
      
@
:
r   rC   c                       e Zd ZeZd Zy)NumberIntervalc                 8   | j                   rt        |      s| j                  | j                  | j                         | j                  t	        | j                  d      | j                  | j                         z  | j                  |      z              z        S |S )Nz1.0)r#   r   r8   rounding_typer   rp   s     r   r}   z"NumberInterval.round_value_by_step  s    99[/99""499-""**51**49956**512	 	 r   N)r   r   r   r   r   r}   r@   r   r   r   r     s    Mr   r   c                   ,     e Zd ZdZeZ fdZd Z xZS )IntIntervalr   c                     t        |t        t        f      r+t        t	        |            t        |      k7  rt        d      t        |   |       y )Nz9Could not coerce %s to int. Decimal places would be lost.)r   r   r   rE   r   r   superro   )r<   rw   r2   s     r   ro   zIntInterval.coerce_obj  sF    cE7+,SX#c(1J#  	3r   c                     | j                   rt        d      | j                  | j                  k7  rt        d      | j                  S )Nz-Empty intervals cannot be coerced to integerszAOnly intervals containing single point can be coerced to integers)r1   r0   r"   r+   rz   s    r   __int__zIntInterval.__int__  sC    ::KLL::#  zzr   )	r   r   r   r#   r   r8   ro   r   __classcell__)r2   s   @r   r   r     s    DD r   r   c                   "    e Zd Z ed      ZeZy)DateIntervalr   )daysN)r   r   r   r   r#   r   r8   r@   r   r   r   r     s    !DDr   r   c                       e Zd ZeZy)DateTimeIntervalN)r   r   r   r   r8   r@   r   r   r   r     s    Dr   r   c                       e Zd ZeZeZy)FloatIntervalN)r   r   r   r   r8   r   r@   r   r   r   r     s    DMr   r   c                       e Zd ZeZd Zd Zy)DecimalIntervalc                     | j                   rft        |      s[| j                  t        t	        | j                         t        dt	        | j                         z  t	        |      z        z              S |S )Ng      ?)r#   r   r8   rE   r   r   rp   s     r   r}   z#DecimalInterval.round_value_by_step  s`    99[/99Sdii uTYY//%,>?@   r   c                 b    	 | j                  |      S # t        t        f$ r t        d      w xY w)Nz(Could not coerce given value to decimal.)r8   r   r0   r   rp   s     r   rn   zDecimalInterval.coerce_string  s9    	U99U## ), 	U()STT	Us    .N)r   r   r   r   r8   r}   rn   r@   r   r   r   r     s    DUr   r   c                       e Zd ZeZd Zy)CharacterIntervalc                 <    t        |t              st        d      |S )NzType %s is not a string.)r   rE   r   rv   s     r   ro   zCharacterInterval.coerce_obj   s    #s#()CDD
r   N)r   r   r   rE   r8   ro   r@   r   r   r   r     s    Dr   r   c                   4    e Zd ZeeeeeegZ	ddZ
ed        Zy)IntervalFactoryNc                     | j                   D ]  }	  |||||      c S  t        d      # t        t        f$ r Y /w xY w)N)r!   r*   r#   Could not initialize interval.)interval_classesr   r0   )r<   rG   r!   r*   r#   interval_classs         r   __call__zIntervalFactory.__call__  s`    "33 		N%''	 		  ,
 	
 &y1 s   +==c                     | j                   D ]  }	 |j                  |      c S  t        d      # t        t        f$ r Y 4w xY w)Nr  )r  ri   r   r0   )r<   r   r  s      r   ri   zIntervalFactory.from_string  sX    "33 	N%11%88	
  ,
 	
 &y1 s   0AAr   )r   r   r   r   r   r   r   r   r   r  r  r   ri   r@   r   r   r   r     s5    
 
 
r   r   )T)F)TF)'__doc__r   r   r   r   decimalr   r   mathr   r	   infinityr
   r   excr   r   r   r   rF   r   r   r   r   r'   r,   r3   rA   objectrC   r   r   r   r   r   r   r   r   Intervalr@   r   r   <module>r     s     . . -  %  95-$22(.D	
v D	
N% $. .# 
' N 
Un U$( "
f "
H r   