Greetings:

I have a class that implements a die (singular or dice).  Here is the class 
definition:

>>>>>>>
class Die(object):
    """Implements a gaming die.

    Attributes:
        n:      the number of sides
                Must correspond to the number of sides on a physical die.
        value:  The die face currently facing up. Guaranteed to be in the
                range 1 <= value <= n.  
        
    Methods:
    init:       instantiate a die
    roll:       roll the die; set and return the new value
    set:        set the die's value to an arbitrary, in range, value
    __repr__   
    __lt__
    __le__
    __eq__
    __ne__
    __gt__
    __ge__
    __cmp__
   
    """
    def __init__(self, nsides = 6, firstval = 'r'):
        """create a die

        usage:  x = die(n, firstval) -> an 'n'-sided die with
                value='firstval'
        Arguments:
            nsides:     the number of sides
                valid:      3,   4,  5,  6,  7,  8,  10, 12, 
                            14, 16, 20, 24, 30, 50, 100
                default:    6
                Must correspond to the number of sides on a physical die.
                Using an invalid value causes an exception.
            firstval:   the die's initial value; 
                valid:      'r' - random value between 1 and n
                             n  - specified value; must be between 1 and n
                                  Using an invalid value causes an 
                                  exception.
                default:    'r'

        """
        validn = (3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 30, 50, 100)
        if nsides not in validn:
            errmsg = "No die has %s sides.  Valid values are: %s." 
            raise ValueError(errmsg % (nsides, validn))
        self.n = nsides

        if firstval == 'r':
            self.value = randint(1, self.n)
        elif isinstance(firstval, int):
            if 1 <= firstval <= self.n:
               self.value =  firstval
            else:
                errmsg = "%s is not between 1 and %s."  
                raise ValueError (errmsg % (firstval, self.n))
        else:
            errmsg = "%s is invalid.  Valid entries are '%s' " \
                     "or an integer between 1 and %s." 
            raise ValueError(errmsg % (firstval, 'r', self.n))
    
    def roll(self):
        """roll the die; set and return the new value"""
        self.value = randint(1, self.n)
        return self.value
    
    def set(self, newval):
        """set the die's new value IF between 1 and n; 
        else raise exception
        
        """
        if isinstance(newval, int):
            if 1 <= newval <= self.n:
               self.value =  newval
            else:
                errmsg = "%s is not between 1 and %s."  
                raise ValueError (errmsg % (newval, self.n))
        else:
            errmsg = "%s is invalid.  Valid entries are ' " \
                     "integers between 1 and %s." 
            raise ValueError(errmsg % (newval, self.n))
    
    # special methods
    def __cast(self, other):
        if isinstance(other, Die): return other.value
        else: return other
    def __repr__(self): return repr(self.value)
    def __lt__(self, other): return self.value <  self.__cast(other)
    def __le__(self, other): return self.value <= self.__cast(other)
    def __eq__(self, other): return self.value == self.__cast(other)
    def __ne__(self, other): return self.value != self.__cast(other)
    def __gt__(self, other): return self.value >  self.__cast(other)
    def __ge__(self, other): return self.value >= self.__cast(other)
    def __cmp__(self, other): return cmp(self.value, self.__cast(other))
>>>>>>>

This all seems to work okay.  

I want the assignment operator ('=') to call the set method transparently on 
Die instances, as in this fictitious example:

#######
@BCARROLL[Python]|2> mydie = Die(6,3)
@BCARROLL[Python]|3> mydie.n
                 <3> 6
@BCARROLL[Python]|4> mydie.value
                 <4> 3
@BCARROLL[Python]|5> mydie
                 <5> 3
@BCARROLL[Python]|6> mydie = 5
@BCARROLL[Python]|7> mydie
                 <7> 5
@BCARROLL[Python]|8> mydie.value
                  8> 5
@BCARROLL[Python]|9>
#######

Above, the statement "mydie = 5" resets mydie.value and preserves mydie as a 
Die instance.  The actual (undesired) behavior rebinds the mydie to the int 
object, and the Die instance is lost:

>>>>>>>
@BCARROLL[Python]|2> mydie = Die(6,3)
@BCARROLL[Python]|3> mydie.n
                 <3> 6
@BCARROLL[Python]|4> mydie.value
                 <4> 3
@BCARROLL[Python]|5> mydie
                 <5> 3
@BCARROLL[Python]|6> mydie = 5
@BCARROLL[Python]|7> mydie
                 <7> 5
@BCARROLL[Python]|8> mydie.value
---------------------------------------------------------------------------
exceptions.AttributeError                 Traceback (most recent call last)

\\psc.pscnet.com\shares\home\bgcarroll\My Documents\My 
Projects\study\Python\<console>

AttributeError: 'int' object has no attribute 'value'
@BCARROLL[Python]|9>
>>>>>>>

How do I overload the '=' operator to give the desired behavior?

Regards,
 
Barry
[EMAIL PROTECTED]
541-302-1107
________________________
We who cut mere stones must always be envisioning cathedrals.
-Quarry worker's creed


_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to