#: c11:FlowerVisitors.py
# Demonstration of "visitor" pattern.
from __future__ import generators
import random

# The Flower hierarchy cannot be changed:
class Flower(object):  
  def accept(self, visitor):
    visitor.visit(self)
  def pollinate(self, pollinator):
    print self, "pollinated by", pollinator
  def eat(self, eater):
    print self, "eaten by", eater
  def __str__(self): 
    return self.__class__.__name__

class Gladiolus(Flower): pass
class Runuculus(Flower): pass
class Chrysanthemum(Flower): pass 

class Visitor:
  def __str__(self): 
    return self.__class__.__name__

class Bug(Visitor): pass
class Pollinator(Bug): pass
class Predator(Bug): pass

# Add the ability to do "Bee" activities:
class Bee(Pollinator):
  def visit(self, flower):
      flower.pollinate(self)

# Add the ability to do "Fly" activities:
class Fly(Pollinator):
  def visit(self, flower):
      flower.pollinate(self)

# Add the ability to do "Worm" activities:
class Worm(Predator):
  def visit(self, flower):
      flower.eat(self)

def flowerGen(n):
  flwrs = Flower.__subclasses__()
  for i in range(n):
    yield random.choice(flwrs)()

# It's almost as if I had a method to Perform
# various "Bug" operations on all Flowers:
bee = Bee()
fly = Fly()
worm = Worm()
for flower in flowerGen(10):
  flower.accept(bee)
  flower.accept(fly)
  flower.accept(worm)
#<hr>
output = '''
Runuculus pollinated by Bee
Runuculus pollinated by Fly
Runuculus eaten by Worm
Chrysanthemum pollinated by Bee
Chrysanthemum pollinated by Fly
Chrysanthemum eaten by Worm
Gladiolus pollinated by Bee
Gladiolus pollinated by Fly
Gladiolus eaten by Worm
Chrysanthemum pollinated by Bee
Chrysanthemum pollinated by Fly
Chrysanthemum eaten by Worm
Chrysanthemum pollinated by Bee
Chrysanthemum pollinated by Fly
Chrysanthemum eaten by Worm
Chrysanthemum pollinated by Bee
Chrysanthemum pollinated by Fly
Chrysanthemum eaten by Worm
Chrysanthemum pollinated by Bee
Chrysanthemum pollinated by Fly
Chrysanthemum eaten by Worm
Gladiolus pollinated by Bee
Gladiolus pollinated by Fly
Gladiolus eaten by Worm
Runuculus pollinated by Bee
Runuculus pollinated by Fly
Runuculus eaten by Worm
Chrysanthemum pollinated by Bee
Chrysanthemum pollinated by Fly
Chrysanthemum eaten by Worm
'''
