'''This Animal class and examples of use are derived from Kirby Urner's work.
Python 2.6
'''
#PY Verbose version:  Comments about Python syntax start with #PY.
#PY Comments to the end of a line start with # - ignored by Python

class Animal:  
    '''Object structure:
       An Animal has a name and a gut (data fields of an Animal object).
       An Animal can greet, eat, and excrete (Animal method names).
    '''

    #PY In Python, the object acted on must always be explicitly named.
    #PY By convention, in a class definition, the current object is called self,
    #PY    so self is the first formal parameter name for *every* object method
    #PY Object methods are function definitions inside the class.
    def __init__(self, aName): #PY construct new Animal, initialize data fields
        '''Create Animal with name aName.''' #PY documentation string
        self.name = aName      #PY Object notation:  object.attribute
                               #PY   Here the self object's name is set to aName
        self.gut = []          # gut initially is an empty list of contents

    def greet(self):
        print "Hello, my name is", self.name # print thing1, thing2, ...

    def eat(self, food):
        self.gut.append(food) # append food to the end of the gut list

    def excrete(self):
        print self.gut.pop(0) # take oldest list item, at position 0

    ######## Conversion to String  ########

    def __str__(self): #PY for conversion to str (string type) and printing
        return 'Animal: ' + self.name
        #PY + used with strings for concatenation

    #PY for conversion to formal string representation that can be used in shell
    def __repr__(self):
        return 'Animal(' + repr(self.name) + ')'
        
#PY indentaton ends, so end of class definition

#PY outside class definition - plain Python function
def testAnimal():   #PY not need parameters; can do stuff and return nothing
    mouse = Animal('Squeeky') #PY object created using class name, not __init__
    mouse.greet()             #PY mouse, before the period is self in definition
    print 'Eat grass and leaf.'
    mouse.eat('grass')        #PY same use of self, but list further parameter
    mouse.eat('leaf')
    print 'Gut contains', mouse.gut  #PY can reference method or data element
    print 'Now excrete:'
    mouse.excrete()
    print 'Gut contains', mouse.gut
    snake = Animal('Hissy')
    snake.greet()
    print 'Eat Squeeky.'
    snake.eat(mouse)
    print 'Gut contains', snake.gut
    print 'In Gut is Animal with gut containing', snake.gut[0].gut #complex ref
    
