On Jun 19, 6:34 pm, apolloni...@gmail.com wrote:
Greetings,
I have been working on a little project today to help me better
understand classes in Python (I really like Python). I am a self
taught programmer and consider myself to fall in the "beginner"
category for sure. It was initially sparked by reading about "state
machines". This was my attempt at it however I feel it is not quite
where it should be:
ON = "ON"
OFF = "OFF"
class LightBulb:
def __init__(self, initial_state):
self.state = initial_state
def TurnOn(self):
if self.state == OFF:
self.state = ON
else:
print "The Bulb Is Already ON!"
def TurnOff(self):
if self.state == ON:
self.state = OFF
else:
print "The Bulb Is Aleady OFF!"
if __name__== "__main__":
light = LightBulb(OFF)
simulation_running = True
while simulation_running:
print "The light is", light.state
print ""
print "Please choose an action:"
print ""
print "[1] Turn Light On"
print "[2] Turn Light Off"
print "[3] Exit Simulation"
print ""
u_choice = raw_input("Please Enter Your Choice: ")
if u_choice == '1':
light.TurnOn()
if u_choice == '2':
light.TurnOff()
elif u_choice == '3':
break
else:
continue
The test portion of the code is actually longer than the class
itself :-) I would like to be able to get a good hold of the concept
with this example before I try to model a more complex problem. Would
someone be willing to give me some feedback on this class and whether
I am on the right track or how I might better go about it?
If all you're implementing is on-or-off logic, then
I'd use the boolean values in Python (True and False),
rather than defining my own 'ON' and 'OFF'. Here
I use __str__ for printing and a _toggle function
to cut down on the possibility of coding errors:
class LightBulb:
def __init__(self, bool):
self.on = bool
def __str__(self):
return self.on and "On" or "Off"
def _toggle(self):
self.on = not self.on
def TurnOn(self):
if self.on: print "\tThe Bulb is ready %s" % self
else: self._toggle()
def TurnOff(self):
if not self.on: print "\tThe Bulb is ready %s" % self
else: self._toggle()
if __name__ == "__main__":
light = LightBulb(False)
while True:
print """
The light is %s
Please choose an action:
[1] Turn Light On
[2] Turn Light Off
[3] Exit
""" % light
u_choice = raw_input("Please Enter Your Choice: ")
if u_choice == '1':
light.TurnOn()
elif u_choice == '2':
light.TurnOff()
elif u_choice == '3':
break
else:
continue
If you're really coding a state machine
wherein many states are possible and many
choices are availble to the user, then I'd refactor.
Rather than having a long sequence of if ... elif ...
elif ... else, perhaps I'd use something like:
import sys
class LightBulb:
def __init__(self, bool):
self.on = bool
def process_instruction(self, wanted):
""" Pass self to unbound method """
try:
LightBulb.instructions[wanted][1](self)
except IndexError:
pass
def __str__(self):
return self.on and "On" or "Off"
def _toggle(self):
self.on = not self.on
def TurnOn(self):
if self.on: print "\n\t** The Bulb is already %s **" % self
else: self._toggle()
def TurnOff(self):
if not self.on: print "\n\t** The Bulb is already %s **" %
self
else: self._toggle()
instructions = ( \
("Exit", sys.exit),
("Turn Light On", TurnOn),
("Turn Light Off", TurnOff),)
if __name__ == "__main__":
light=LightBulb(False)
usage=["\t%d: %s" % (i,t[0]) for i,t in
enumerate(LightBulb.instructions)]
usage.insert(0, "\n\tThe light is %s\n\tPlease choose an action:")
prompt = "\n".join(usage)
while True:
print prompt % light
u_choice = raw_input("\nPlease Enter Your Choice: ")
try:
light.process_instruction(int(u_choice))
except ValueError:
pass
Note that I can add intructions as needed to
LightBulb.instructions and not have to change the
user interface.
--
Hope this helps,
Steven