]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
adapted to new overloading scheme
authorGuido van Rossum <guido@python.org>
Sun, 9 Oct 1994 22:36:28 +0000 (22:36 +0000)
committerGuido van Rossum <guido@python.org>
Sun, 9 Oct 1994 22:36:28 +0000 (22:36 +0000)
Demo/classes/Dates.py
Demo/classes/Rat.py

index 4e8bbf709ce2dc5e0d7347db7e7fa925d79d0f85..7f55d24df518c87cd11a5ceb9081697390a486ff 100755 (executable)
@@ -16,7 +16,7 @@
 # Date objects support one visible method, date.weekday().  This returns
 # the day of the week the date falls on, as a string.
 #
-# Date objects also have 4 (conceptually) read-only data attributes:
+# Date objects also have 4 read-only data attributes:
 #   .month  in 1..12
 #   .day    in 1..31
 #   .year   int or long int
 # Tim Peters   tim@ksr.com
 # not speaking for Kendall Square Research Corp
 
+# Adapted to Python 1.1 (where some hacks to overcome coercion are unnecessary)
+# by Guido van Rossum
+
+# vi:set tabsize=8:
+
 _MONTH_NAMES = [ 'January', 'February', 'March', 'April', 'May',
                 'June', 'July', 'August', 'September', 'October',
                 'November', 'December' ]
@@ -81,6 +86,7 @@ def _num2date( n ):           # return date with ordinal n
        raise TypeError, 'argument must be integer: ' + `type(n)`
 
     ans = Date(1,1,1)  # arguments irrelevant; just getting a Date obj
+    del ans.ord, ans.month, ans.day, ans.year # un-initialize it
     ans.ord = n
 
     n400 = (n-1)/_DI400Y               # # of 400-year blocks preceding
@@ -93,7 +99,7 @@ def _num2date( n ):           # return date with ordinal n
     year, n = year + more, int(n - dby)
 
     try: year = int(year)              # chop to int, if it fits
-    except ValueError: pass
+    except (ValueError, OverflowError): pass
 
     month = min( n/29 + 1, 12 )
     dbm = _days_before_month( month, year )
@@ -118,6 +124,12 @@ class Date:
        self.month, self.day, self.year = month, day, year
        self.ord = _date2num( self )
 
+    # don't allow setting existing attributes
+    def __setattr__( self, name, value ):
+       if self.__dict__.has_key(name):
+           raise AttributeError, 'read-only attribute ' + name
+       self.__dict__[name] = value
+
     def __cmp__( self, other ):
        return cmp( self.ord, other.ord )
 
@@ -132,52 +144,27 @@ class Date:
              self.day,
              _MONTH_NAMES[self.month-1] ) + `self.year`
 
-    # automatic coercion is a pain for date arithmetic, since e.g.
-    # date-date and date-int mean different things.  So, in order to
-    # sneak integers past Python's coercion rules without losing the info
-    # that they're really integers (& not dates!), integers are disguised
-    # as instances of the derived class _DisguisedInt.  That this works
-    # relies on undocumented behavior of Python's coercion rules.
-    def __coerce__( self, other ):
-       if type(other) in _INT_TYPES:
-           return self, _DisguisedInt(other)
-       # if another Date, fine
-       if type(other) is type(self) and other.__class__ is Date:
-           return self, other
-
-    # Python coerces int+date, but not date+int; in the former case,
-    # _DisguisedInt.__add__ handles it, so we only need to do
-    # date+int here
+    # Python 1.1 coerces neither int+date nor date+int
     def __add__( self, n ):
        if type(n) not in _INT_TYPES:
            raise TypeError, 'can\'t add ' + `type(n)` + ' to date'
        return _num2date( self.ord + n )
+    __radd__ = __add__ # handle int+date
 
-    # Python coerces all of int-date, date-int and date-date; the first
-    # case winds up in _DisguisedInt.__sub__, leaving the latter two
-    # for us
+    # Python 1.1 coerces neither date-int nor date-date
     def __sub__( self, other ):
-       if other.__class__ is _DisguisedInt:    # date-int
-           return _num2date( self.ord - other.ord )
+       if type(other) in _INT_TYPES:           # date-int
+           return _num2date( self.ord - other )
        else:
            return self.ord - other.ord         # date-date
 
-    def weekday( self ):
-       return _num2day( self.ord )
-
-# see comments before Date.__add__
-class _DisguisedInt( Date ):
-    def __init__( self, n ):
-       self.ord = n
-
-    # handle int+date
-    def __add__( self, other ):
-       return other.__add__( self.ord )
-
     # complain about int-date
-    def __sub__( self, other ):
+    def __rsub__( self, other ):
        raise TypeError, 'Can\'t subtract date from integer'
 
+    def weekday( self ):
+       return _num2day( self.ord )
+
 def today():
     import time
     local = time.localtime(time.time())
@@ -189,9 +176,7 @@ def test( firstyear, lastyear ):
     b = Date(9,30,1914)
     if `a` != 'Tue 30 Sep 1913':
        raise DateTestError, '__repr__ failure'
-    if (not a < b) or a == b or a > b or b != b or \
-         a != 698982 or 698982 != a or \
-         (not a > 5) or (not 5 < a):
+    if (not a < b) or a == b or a > b or b != b:
        raise DateTestError, '__cmp__ failure'
     if a+365 != b or 365+a != b:
        raise DateTestError, '__add__ failure'
index d10e4dfac43dd961893d25e4b0839931509b5d61..755374570611e21c6cde2bcc14612c74427a692e 100755 (executable)
@@ -1,7 +1,10 @@
 # Rational numbers
 
+from types import *
 
 def rat(num, den):
+       if type(num) == FloatType or type(den) == FloatType:
+               return num/den
        return Rat(num, den)
 
 
@@ -16,12 +19,21 @@ class Rat:
        def __init__(self, num, den):
                if den == 0:
                        raise ZeroDivisionError, 'rat(x, 0)'
-               g = gcd(num, den)
+               if type(den) == FloatType or type(num) == FloatType:
+                       g = float(den)
+               else:
+                       g = gcd(num, den)
                self.num = num/g
                self.den = den/g
 
        def __repr__(self):
-               return 'rat' + `self.num, self.den`
+               return 'Rat(%s, %s)' % (self.num, self.den)
+
+       def __str__(self):
+               if self.den == 1:
+                       return str(self.num)
+               else:
+                       return '%s/%s' % (self.num, self.den)
 
        def __cmp__(a, b):
                c = a-b
@@ -42,29 +54,23 @@ class Rat:
 
        def __coerce__(a, b):
                t = type(b)
-               if t == type(0):
-                       return a, rat(b, 1)
-               if t == type(0L):
-                       return a, rat(b, 1L)
-               if t == type(0.0):
-                       return a.__float__(), b
-               if t == type(a) and a.__class__ == b.__class__:
+               if t == IntType:
+                       return a, Rat(b, 1)
+               if t == LongType:
+                       return a, Rat(b, 1L)
+               if t == FloatType:
+                       return a, Rat(b, 1.0)
+               if t == InstanceType and a.__class__ == b.__class__:
                        return a, b
                raise TypeError, 'Rat.__coerce__: bad other arg'
 
        def __add__(a, b):
-               if type(b) <> type(a):
-                       a, b = a.__coerce__(b)
-                       return a + b
                return rat(a.num*b.den + b.num*a.den, a.den*b.den)
 
        def __sub__(a, b):
                return rat(a.num*b.den - b.num*a.den, a.den*b.den)
 
        def __mul__(a, b):
-               if type(b) <> type(a):
-                       a, b = a.__coerce__(b)
-                       return a * b
                return rat(a.num*b.num, a.den*b.den)
 
        def __div__(a, b):
@@ -75,21 +81,21 @@ class Rat:
 
 
 def test():
-       print rat(-1L, 1)
-       print rat(1, -1)
-       a = rat(1, 10)
+       print Rat(-1L, 1)
+       print Rat(1, -1)
+       a = Rat(1, 10)
        print int(a), long(a), float(a)
-       b = rat(2, 5)
+       b = Rat(2, 5)
        l = [a+b, a-b, a*b, a/b]
        print l
        l.sort()
        print l
-       print rat(0, 1)
+       print Rat(0, 1)
        print a+1
        print a+1L
        print a+1.0
        try:
-               print rat(1, 0)
+               print Rat(1, 0)
                raise SystemError, 'should have been ZeroDivisionError'
        except ZeroDivisionError:
                print 'OK'