__iter__ goes through the digits - allowing gui code to build digit boxes easily.
e.g.:
>>> print maths_4_N_13.LongDivFormatted(15670,3)
5,223
-------- R=1
3 | 15,670
>>>
from types import IntType, LongType
THOUSANDS_SEP = ','
DECIMAL_SEP = ''
class TeachingWholeNumber(object):
"""An integer whole number (>= 0) where each digit is addressable
list style. the 0th element of the 'digits' attribute
is the ones place, the 1st element is the
tens place and so on.
"""
def __init__(self,n=0):
"""New object with default value of 0
"""
if n == 0:
self.digits=[0]
else:
n=int(n)
self.digits=[]
while n > 0:
self.digits.append(n%10)
n=n/10
def __int__(self):
"""Returns the corresponding integer value
"""
retValue = 0
for i,v in enumerate(self.digits):
retValue += (10**i)*v
return retValue
#
# listy methods
#
def __len__(self):
"""Returns the length of the digits list
"""
return len(self.digits)
def __getitem__(self,i):
if type(i) not in (IntType,LongType):
return TypeError, "Index must be an integer type"
else:
return self.digits[i]
def __setitem__(self,i,v):
if type(i) not in (IntType,LongType):
return TypeError, "Index must be an integer type"
if type(v) != IntType or v > 9 or v < 0:
return ValueError, "value, v, must be an integer between 0 and 9"
if i < len(self):
self.digits[i]=v
elif v > 0:
# appending 0 past the last non-zero is a null op
while i> len(self):
self.digits.append(0)
self.digits.append(v)
#
# Expected methods for number-like type
#
def __lt__(self, other):
return int(self) < int(other)
def __le__(self, other):
return int(self) <= int(other)
def __eq__(self, other):
return int(self) == int(other)
def __ne__(self, other):
return int(self) != int(other)
def __gt__(self, other):
return int(self) > int(other)
def __ge__(self, other):
return int(self) >= int(other)
def __add__(self, other):
return self.__class__(int(self)+int(other))
def __sub__(self, other):
return self.__class__(int(self)-int(other))
def __mul__(self, other):
return self.__class__(int(self)*int(other))
def __floordiv__(self, other):
return self.__class__(int(self)/int(other))
def __mod__(self, other):
return self.__class__(int(self)%int(other))
def __divmod__(self, other):
return tuple([self.__class__(x)
for x in divmod(int(self),int(other))])
def __pow__(self, other):
return
def __lshift__(self, other):
return NotImplemented
def __rshift__(self, other):
return NotImplemented
def __and__(self, other):
return NotImplemented
def __xor__(self, other):
return NotImplemented
def __or__(self, other):
return NotImplemented
def __div__(self, other):
return self.__class__(int(self)/int(other))
def __truediv__(self, other):
return NotImplemented
def __neg__(self):
return NotImplemented
def __pos__(self):
return NotImplemented
def __abs__(self):
return abs(int(self))
def __invert__(self):
return NotImplemented
def __complex__(self):
return NotImplemented
def __long__(self):
return long(int(self))
def __float__(self):
return float(int(self))
def __repr__(self):
return str(int(self))
def __str__(self):
"""pretty string
"""
dgtList=[]
for i,v in enumerate(self):
if i>0 and (i-1)%3 == 2:
dgtList.append(THOUSANDS_SEP)
dgtList.append(str(v))
dgtList.reverse()
return ''.join(dgtList)
def rshift(self,places=1):
"""right shift (in base 10) disgarding 'places' least significant digits
Arguments:
- `self`:
- `places`:
"""
# is this better implememted by overriding >> ?
while places > 0:
self.digits.pop(0)
places -= 1
def lshift(self,places=1):
"""left shift (in base 10) disgarding 'places' least significant digits.
Arguments:
- `self`:
- `places`:
"""
# is this better implememted by overriding << ?
while places > 0:
self.digits.insert(0,0)
places -= 1
def randomTWN(low,high):
"""factory fcn to return a random TeachingWholeNumber,
between low and high inclusive.
"""
if high < 0 or low < 0:
raise ValueError, "high and low must be > 0"
i = random.randint(low,high)
return TeachingWholeNumber(i)
class Division (object):
"""Division Container
"""
def __init__ (self,dividend,divisor):
"""New one!
"""
self.dividend = dividend
self.divisor = divisor
self.quotent, self.remainder = divmod(dividend,divisor)
class LongDivFormatted(Division):
"""Knows how to print itself
"""
leftMargin = 1
rightMargin = 2
midMargin = 1
vertbar='|'
horizbar='-'
def __init__ (self,dividend,divisor,useTWN=True):
"""New one!
"""
if useTWN:
dividend=TeachingWholeNumber(dividend)
divisor=TeachingWholeNumber(divisor)
Division.__init__(self,dividend,divisor)
def __str__ (self):
"""ASCII representation.
"""
mainWidth = (self.leftMargin+
len(str(self.divisor))+
(self.midMargin *2)+
len(self.vertbar)+
len(str(self.dividend)))
remainderWidth = ((self.rightMargin) +
len(str(self.remainder))+
len('R='))
totalWidth = mainWidth+remainderWidth
retLines=[]
retLines.append(('%'+str(mainWidth)+'s')%(self.quotent))
retLines.append((' '*(self.leftMargin +
len(str(self.divisor))+
self.midMargin)) +
(self.horizbar*(len(self.vertbar)+
self.midMargin+
len(str(self.dividend)))) +
('%'+str(remainderWidth)+'s')%('R='+str(self.remainder)))
retLines.append((' ' * self.leftMargin) +
str(self.divisor) +
(' ' * self.midMargin) +
self.vertbar +
(' ' * self.midMargin) +
str(self.dividend))
return '\n'.join(retLines)
No comments:
Post a Comment