meta data for this page
  •  

exer_fsm_impl Result Code

for exer_fsm_impl

package: exer_fsm_impl

main.py

import logging
log = logging.getLogger(__name__)

import exer_fsm_impl.user as mu
import exer_fsm_impl.vending_machine as mvm

def run():
  vm = mvm.VendingMachine()
  user = mu.User(vm)
  vm.set_user(user)
  user.run()

if __name__ == '__main__':
  logging.basicConfig(level=logging.DEBUG)  
  run()

interfaces.py

class IFrontPanel(object):
  '''
  Interface to VendingMachine.
  User => VendingMachine
  '''
  
  def insert_coin(self,coin):
    raise NotImplementedError()
  
  def return_coins(self):
    raise NotImplementedError()

  def Kola(self):
    raise NotImplementedError()

  def Vissy(self):
    raise NotImplementedError()

  def Jaffa(self):
    raise NotImplementedError()

  def Muumi(self):
    raise NotImplementedError()

  def poweroff(self):
    raise NotImplementedError()

  def shutdown_timeout(self):
    raise NotImplementedError()

  # lets see if this is needed
  #def coins_ok(self):
  #  raise NotImplementedError()

class IUser(object):
  
  def display(self,text):
    raise NotImplementedError()
 
  def error(self,text):
    raise NotImplementedError()

  def delivery(self,text):
    raise NotImplementedError()

user.py

import cmd
import sys

import logging
log = logging.getLogger(__name__)

from exer_fsm_impl.interfaces import *

class User(cmd.Cmd,IUser):

  def __init__(self,vm):
    cmd.Cmd.__init__(self)
    self._vm = vm

  def do_coins(self,amount):
    """ coins <money> -- Insert coins """
    try:
      amount = float(amount)
    except ValueError, e:
      print "Usage: coins <money as a real number>"
      return  
    self._vm.insert_coin(amount)

  def do_return(self,arg):
    """ -- return money """
    self._vm.return_coins()
    
  def do_kola(self,arg):
    """ -- deliver Kola drink """
    self._vm.Kola()
    
  def do_vissy(self,arg):
    """ -- deliver Vissy drink """
    self._vm.Vissy()
    
  def do_muumi(self,arg):
    """ -- deliver Muumi drink """
    self._vm.Muumi()
    
  def do_jaffa(self,arg):
    """ -- deliver Jaffa drink """
    self._vm.Jaffa()
    
  def do_poweroff(self,arg):
    """ -- quit interaction """
    self._vm.poweroff()

  def display(self,text):
    print "[[ " + text + "]]"
 
  def error(self,text):
    print "Error !! " + text + " !!"

  def delivery(self,text):
    print "Deliver ==> " + text + " <=="

  def run(self):
    log.debug("User.run ..")
    self.cmdloop("Vending Machine:")

vending_machine.py

import logging
log = logging.getLogger(__name__)
import threading
import sys

from exer_fsm_impl.interfaces import *

class VendingMachine(IFrontPanel):
  
  ## States
  
  class State(object):
    
    def name(self):
      raise NotImplementedError()
    
    def insert_coin(self,ctx,coin):
      log.error("insert_coin wrong state")

    def return_coins(self,ctx):
      log.error("return_coins wrong state")      

    def Kola(self,ctx):
      log.error("Kola wrong state")      
    
    def Vissy(self,ctx):
      log.error("Vissy wrong state")      

    def Jaffa(self,ctx):
      log.error("Jaffa wrong state")      

    def Muumi(self,ctx):
      log.error("Muumi wrong state")
      
    def poweroff(self,ctx):
      ctx._user.delivery("return coins " + 
                         str(ctx._money))
      ctx._money = 0
      ctx._user.display("SHUTDOWN")
      ctx.changeState(ctx.SHUTDOWN)
      timer = threading.Timer(3,ctx.shutdown_timeout)
      timer.start()
      
    def shutdown_timeout(self,ctx):
      log.error("shutdown_timeout wrong state")
            
  class Idle(State):
    
    def name(self):
      return "IDLE"
    
    def insert_coin(self,ctx,coin):
      ctx._money += coin
      ctx._user.display("Money: " + str(ctx._money))      
      ctx.changeState(ctx.WF_COINS)  

  class WfCoins(State):
    
    def name(self):
      return "WF_COINS"
    
    def insert_coin(self,ctx,coin):
      ctx._money += coin
      ctx._user.display("Money: " + str(ctx._money))      
      if ctx._money >= ctx._prize:
        ctx.changeState(ctx.WF_DRINK)
      else:
        ctx.changeState(ctx.WF_COINS)        

    def return_coins(self,ctx):
      ctx._user.delivery("return coins " + 
                         str(self._money))
      ctx._money = 0
      ctx.changeState(ctx.IDLE)

  class WfDrink(State):
    
    def name(self):
      return "WF_DRINK"
    
    def insert_coin(self,ctx,coin):
      ctx._money += coin
      ctx._user.display("Money: " + str(ctx._money))
      ctx.changeState(ctx.WF_DRINK)

    def return_coins(self,ctx):
      ctx._user.delivery("return coins " + 
                         str(self._money))
      ctx._money = 0
      ctx.changeState(ctx.IDLE)

    def Kola(self,ctx):
      ctx._money -= ctx._prize
      ctx._user.delivery("KOLA")
      ctx._user.delivery("return coins " + 
                         str(ctx._money))
      ctx._money = 0
      ctx.changeState(ctx.IDLE)
    
    def Vissy(self,ctx):
      ctx._money -= ctx._prize
      ctx._user.delivery("VISSY")
      ctx._user.delivery("return coins " + 
                         str(ctx._money))
      ctx._money = 0
      ctx.changeState(ctx.IDLE)

    def Jaffa(self,ctx):
      ctx._money -= ctx._prize      
      ctx._user.delivery("JAFFA")
      ctx._user.delivery("return coins " + 
                         str(ctx._money))
      ctx._money = 0
      ctx.changeState(ctx.IDLE)

    def Muumi(self,ctx):
      ctx._money -= ctx._prize
      ctx._user.delivery("MUUMI")
      ctx._user.delivery("return coins " + 
                         str(ctx._money))
      ctx._money = 0
      ctx.changeState(ctx.IDLE)

  class Shutdown(State):
    
    def name(self):
      return "SHUTDOWN"
    
    def shutdown_timeout(self,ctx):
      ctx._user.display("POWER OFF")
      sys.exit()
    
  ## Operations

  def __init__(self):
    self._user = None
    self._money = 0 # Money in the vending machine
    self._prize = 2.4 # Prize of the drink
    ## State
    self.IDLE = VendingMachine.Idle()
    self.WF_COINS = VendingMachine.WfCoins()
    self.WF_DRINK = VendingMachine.WfDrink()
    self.SHUTDOWN = VendingMachine.Shutdown()
    ## State variable and initial state
    self._state = self.IDLE
    
  def set_user(self,user):
    self._user = user

  def changeState(self,newState):
    log.debug("state change " + self._state.name() +
              " => " + newState.name())
    self._state = newState

  ## Message delegation
  
  def insert_coin(self,coin):
    self._state.insert_coin(self, coin)
  
  def return_coins(self):
    self._state.return_coins(self)

  def Kola(self):
    self._state.Kola(self)

  def Vissy(self):
    self._state.Vissy(self)

  def Jaffa(self):
    self._state.Jaffa(self)

  def Muumi(self):
    self._state.Muumi(self)
    
  def poweroff(self):
    self._state.poweroff(self)
  
  def shutdown_timeout(self):
    self._state.shutdown_timeout(self)