Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2e61103

Browse files
committed
adapted to new overloading scheme
1 parent 74233b3 commit 2e61103

2 files changed

Lines changed: 51 additions & 60 deletions

File tree

Demo/classes/Dates.py

Lines changed: 24 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# Date objects support one visible method, date.weekday(). This returns
1717
# the day of the week the date falls on, as a string.
1818
#
19-
# Date objects also have 4 (conceptually) read-only data attributes:
19+
# Date objects also have 4 read-only data attributes:
2020
# .month in 1..12
2121
# .day in 1..31
2222
# .year int or long int
@@ -33,6 +33,11 @@
3333
# Tim Peters [email protected]
3434
# not speaking for Kendall Square Research Corp
3535

36+
# Adapted to Python 1.1 (where some hacks to overcome coercion are unnecessary)
37+
# by Guido van Rossum
38+
39+
# vi:set tabsize=8:
40+
3641
_MONTH_NAMES = [ 'January', 'February', 'March', 'April', 'May',
3742
'June', 'July', 'August', 'September', 'October',
3843
'November', 'December' ]
@@ -81,6 +86,7 @@ def _num2date( n ): # return date with ordinal n
8186
raise TypeError, 'argument must be integer: ' + `type(n)`
8287

8388
ans = Date(1,1,1) # arguments irrelevant; just getting a Date obj
89+
del ans.ord, ans.month, ans.day, ans.year # un-initialize it
8490
ans.ord = n
8591

8692
n400 = (n-1)/_DI400Y # # of 400-year blocks preceding
@@ -93,7 +99,7 @@ def _num2date( n ): # return date with ordinal n
9399
year, n = year + more, int(n - dby)
94100

95101
try: year = int(year) # chop to int, if it fits
96-
except ValueError: pass
102+
except (ValueError, OverflowError): pass
97103

98104
month = min( n/29 + 1, 12 )
99105
dbm = _days_before_month( month, year )
@@ -118,6 +124,12 @@ def __init__( self, month, day, year ):
118124
self.month, self.day, self.year = month, day, year
119125
self.ord = _date2num( self )
120126

127+
# don't allow setting existing attributes
128+
def __setattr__( self, name, value ):
129+
if self.__dict__.has_key(name):
130+
raise AttributeError, 'read-only attribute ' + name
131+
self.__dict__[name] = value
132+
121133
def __cmp__( self, other ):
122134
return cmp( self.ord, other.ord )
123135

@@ -132,52 +144,27 @@ def __repr__( self ):
132144
self.day,
133145
_MONTH_NAMES[self.month-1] ) + `self.year`
134146

135-
# automatic coercion is a pain for date arithmetic, since e.g.
136-
# date-date and date-int mean different things. So, in order to
137-
# sneak integers past Python's coercion rules without losing the info
138-
# that they're really integers (& not dates!), integers are disguised
139-
# as instances of the derived class _DisguisedInt. That this works
140-
# relies on undocumented behavior of Python's coercion rules.
141-
def __coerce__( self, other ):
142-
if type(other) in _INT_TYPES:
143-
return self, _DisguisedInt(other)
144-
# if another Date, fine
145-
if type(other) is type(self) and other.__class__ is Date:
146-
return self, other
147-
148-
# Python coerces int+date, but not date+int; in the former case,
149-
# _DisguisedInt.__add__ handles it, so we only need to do
150-
# date+int here
147+
# Python 1.1 coerces neither int+date nor date+int
151148
def __add__( self, n ):
152149
if type(n) not in _INT_TYPES:
153150
raise TypeError, 'can\'t add ' + `type(n)` + ' to date'
154151
return _num2date( self.ord + n )
152+
__radd__ = __add__ # handle int+date
155153

156-
# Python coerces all of int-date, date-int and date-date; the first
157-
# case winds up in _DisguisedInt.__sub__, leaving the latter two
158-
# for us
154+
# Python 1.1 coerces neither date-int nor date-date
159155
def __sub__( self, other ):
160-
if other.__class__ is _DisguisedInt: # date-int
161-
return _num2date( self.ord - other.ord )
156+
if type(other) in _INT_TYPES: # date-int
157+
return _num2date( self.ord - other )
162158
else:
163159
return self.ord - other.ord # date-date
164160

165-
def weekday( self ):
166-
return _num2day( self.ord )
167-
168-
# see comments before Date.__add__
169-
class _DisguisedInt( Date ):
170-
def __init__( self, n ):
171-
self.ord = n
172-
173-
# handle int+date
174-
def __add__( self, other ):
175-
return other.__add__( self.ord )
176-
177161
# complain about int-date
178-
def __sub__( self, other ):
162+
def __rsub__( self, other ):
179163
raise TypeError, 'Can\'t subtract date from integer'
180164

165+
def weekday( self ):
166+
return _num2day( self.ord )
167+
181168
def today():
182169
import time
183170
local = time.localtime(time.time())
@@ -189,9 +176,7 @@ def test( firstyear, lastyear ):
189176
b = Date(9,30,1914)
190177
if `a` != 'Tue 30 Sep 1913':
191178
raise DateTestError, '__repr__ failure'
192-
if (not a < b) or a == b or a > b or b != b or \
193-
a != 698982 or 698982 != a or \
194-
(not a > 5) or (not 5 < a):
179+
if (not a < b) or a == b or a > b or b != b:
195180
raise DateTestError, '__cmp__ failure'
196181
if a+365 != b or 365+a != b:
197182
raise DateTestError, '__add__ failure'

Demo/classes/Rat.py

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# Rational numbers
22

3+
from types import *
34

45
def rat(num, den):
6+
if type(num) == FloatType or type(den) == FloatType:
7+
return num/den
58
return Rat(num, den)
69

710

@@ -16,12 +19,21 @@ class Rat:
1619
def __init__(self, num, den):
1720
if den == 0:
1821
raise ZeroDivisionError, 'rat(x, 0)'
19-
g = gcd(num, den)
22+
if type(den) == FloatType or type(num) == FloatType:
23+
g = float(den)
24+
else:
25+
g = gcd(num, den)
2026
self.num = num/g
2127
self.den = den/g
2228

2329
def __repr__(self):
24-
return 'rat' + `self.num, self.den`
30+
return 'Rat(%s, %s)' % (self.num, self.den)
31+
32+
def __str__(self):
33+
if self.den == 1:
34+
return str(self.num)
35+
else:
36+
return '%s/%s' % (self.num, self.den)
2537

2638
def __cmp__(a, b):
2739
c = a-b
@@ -42,29 +54,23 @@ def __int__(self):
4254

4355
def __coerce__(a, b):
4456
t = type(b)
45-
if t == type(0):
46-
return a, rat(b, 1)
47-
if t == type(0L):
48-
return a, rat(b, 1L)
49-
if t == type(0.0):
50-
return a.__float__(), b
51-
if t == type(a) and a.__class__ == b.__class__:
57+
if t == IntType:
58+
return a, Rat(b, 1)
59+
if t == LongType:
60+
return a, Rat(b, 1L)
61+
if t == FloatType:
62+
return a, Rat(b, 1.0)
63+
if t == InstanceType and a.__class__ == b.__class__:
5264
return a, b
5365
raise TypeError, 'Rat.__coerce__: bad other arg'
5466

5567
def __add__(a, b):
56-
if type(b) <> type(a):
57-
a, b = a.__coerce__(b)
58-
return a + b
5968
return rat(a.num*b.den + b.num*a.den, a.den*b.den)
6069

6170
def __sub__(a, b):
6271
return rat(a.num*b.den - b.num*a.den, a.den*b.den)
6372

6473
def __mul__(a, b):
65-
if type(b) <> type(a):
66-
a, b = a.__coerce__(b)
67-
return a * b
6874
return rat(a.num*b.num, a.den*b.den)
6975

7076
def __div__(a, b):
@@ -75,21 +81,21 @@ def __neg__(self):
7581

7682

7783
def test():
78-
print rat(-1L, 1)
79-
print rat(1, -1)
80-
a = rat(1, 10)
84+
print Rat(-1L, 1)
85+
print Rat(1, -1)
86+
a = Rat(1, 10)
8187
print int(a), long(a), float(a)
82-
b = rat(2, 5)
88+
b = Rat(2, 5)
8389
l = [a+b, a-b, a*b, a/b]
8490
print l
8591
l.sort()
8692
print l
87-
print rat(0, 1)
93+
print Rat(0, 1)
8894
print a+1
8995
print a+1L
9096
print a+1.0
9197
try:
92-
print rat(1, 0)
98+
print Rat(1, 0)
9399
raise SystemError, 'should have been ZeroDivisionError'
94100
except ZeroDivisionError:
95101
print 'OK'

0 commit comments

Comments
 (0)