By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,365 Members | 1,390 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,365 IT Pros & Developers. It's quick & easy.

Help With Better Design

P: n/a
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?

Jun 20 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a
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

Jun 20 '07 #2

P: n/a
En Tue, 19 Jun 2007 22:34:27 -0300, <ap*********@gmail.comescribió:
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:
That's rather good as it is!
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!"
One could argue here: is it an error to attempt to turn the light on
again, if it is already on?
If yes: raising an exception is the usual way to report error conditions
(let the caller handle it, if he cares enough)
If not: why to check the current state? Just set the new state as ON,
whatever was the prior state.
The same for TurnOff. (BTW, the reccomended style is to use lower_case
(best) or mixedCase for method names: turn_on or turnOn)
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 :-)
That's often the case!
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?
The example is fine. You could move on from "interactive testing" (your
"demo" program, where a human runs some code, more-or-less at random, sees
the results and judges by himself if it is "OK" or "wrong") into
"automated unit testing": an automated sequence of tests, each with its
input and expected output, that can be executed automatically and without
any human intervention.

There is a framework for writing those (see the unittest module), but you
can start just by using the assert statement:

light = LightBulb(OFF)
assert light.state == OFF # ensure that it gets initialized correctly
light.TurnOn()
assert light.state == ON # ensure that TurnOn actually does as intended
light.TurnOff()
assert light.state == OFF
light.TurnOff()
assert light.state == OFF # an attempt to turn it off again should leave
it off
light.TurnOn()
light.TurnOn() # an attempt to turn it on again
assert light.state == ON
# some more tests
light = LightBulb(ON)
assert light.state == ON # should test both initial states
light = LightBulb(0) # what should happen here?
light.TurnOn()
assert light.state == ON # oops!
light.TurnOff()
assert light.state == OFF # oops!

This has many advantages: you can write the tests carefully once and run
many times later, and detect breakages; you can't take a "likely" answer
for a "true" answer; etc.

--
Gabriel Genellina

Jun 20 '07 #3

P: n/a
Thank you both for the insightful responses(I knew I came to the right
place)!

Steven -- The original inspiration was a "State Machine" your code re-
write was what I was trying to accomplish but quickly got in way over
my head. Thank you for expanding on that aspect of it. That will give
me some really good material to learn with. I wanted to be able to
seamlessly add new new states like say "flash" without changing the
code in many different places. I have great appreciation for OO design
(respect those who can successfully implement it); I just find it has
quite a learning curve.

Gabriel -- Thanks for the encouragement; despite it's simplistic
nature it took me a good bit of time to get working...I'm getting a
little faster the more I code. I like the insight on the testing
aspect of it. I found that I always try to test my code using
"interactive testing" as you called it. This can lead me to getting
bogged down in trying to "out smart" the user (who is only me anyway)
and spend less time actually testing the code (this is probably a
common problem). Never really thought about writing a test module just
to see if the darn thing works! Oh and I know better on the syntax
thing thanks for catching it and calling it out.

Going to rework and go from there (I feel some new questions coming
on...)

Thanks again for the nudge in the right direction!

Jun 20 '07 #4

P: n/a
ap*********@gmail.com a écrit :
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:
First, a few general comments
ON = "ON"
OFF = "OFF"

class LightBulb:
Better to use newstyle classes:
class LightBulb(object):
def __init__(self, initial_state):
self.state = initial_state

def TurnOn(self):
Pep-08 (naming conventions):
def turn_on(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!"

What about:

class LightBulb(object):
def __init__(self, state):
self.state = state

def switch(self):
self.state = not self.state

(snip)
I would like to be able to get a good hold of the concept
state machines ?
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?
There is a lot to say about OO and state machines. Someone once defined
the use of OO in simulations as "building an big unpredictable state
machine from small predictable state machines". As a matter of fact,
objects are (most of the time) informal state machines (they have state,
and they have behaviour depending on state). Now there are much more
formal state machines (google for "FSM" or "finite state machine") -
which can be implemented in a lot of ways - including the "State" design
pattern.

Before jumping to implementation, you should probably try to model the
"more complex problem" with something like UML state diagram (one of the
few usable things in UML).

My 2 cents
Jun 20 '07 #5

P: n/a
I've written code that looks a lot like that, and it's
a perfectly acceptable pattern IMHO. I don't bother
with the variables ON and OFF, though, as they add no
clarity to simply using 'ON' and 'OFF' for the states.

[...]
The test portion of the code is actually longer than
the class
itself :-)

That's usually a good thing! It means your code is
concise, and your tests are exhaustive. (But that
doesn't mean you can't also refactor your tests.)
I have a habit of falling into the ole' "re-invent the wheel" trap. As
long as I can be thurough without veering too far off course i'm in
good shape.

---------------------------------------------------------------------------------------------------
>
Better to use newstyle classes:
class LightBulb(object):
def __init__(self, initial_state):
self.state = initial_state
def TurnOn(self):

Pep-08 (naming conventions):
def turn_on(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!"
Thanks for mentioning that as I have never looked at PEP-08 before
(just looked it up) and I bookmarked it for future reference.
What about:

class LightBulb(object):
def __init__(self, state):
self.state = state

def switch(self):
self.state = not self.state

(snip)
I never thought about it using a switch. Steven eluded to it (toggle)
in his re-write of the code. I plan on using that idea.
I would like to be able to get a good hold of the concept

state machines ?
Well both state machines and classes (objects). That may be a bit of a
tall order to take on all at once but the concepts seem to be quite
related. I already have a great deal of material on Classes so good to
go there. The state machine idea came from a game tutorial I was
reading and it really sparked my interest.
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?

There is a lot to say about OO and state machines. Someone once defined
the use of OO in simulations as "building an big unpredictable state
machine from small predictable state machines". As a matter of fact,
objects are (most of the time) informal state machines (they have state,
and they have behaviour depending on state). Now there are much more
formal state machines (google for "FSM" or "finite state machine") -
which can be implemented in a lot of ways - including the "State" design
pattern.

Before jumping to implementation, you should probably try to model the
"more complex problem" with something like UML state diagram (one of the
few usable things in UML).
Thanks. Found some good FSM articles, that should help.

Jun 20 '07 #6

P: n/a
ap*********@gmail.com a écrit :
(snip)
>>I would like to be able to get a good hold of the concept
state machines ?

Well both state machines and classes (objects). That may be a bit of a
tall order to take on all at once but the concepts seem to be quite
related.
They are, since OO was born from the use of state machines for
simulation (the Simula language). But you can do state machines with a
database and a procedural language too, and FWIW, the "state machine"
aspect of OO is more often very informal and ad hoc.
I already have a great deal of material on Classes so good to
go there.
Don't confuse "classes" with OO. The "OO" in OOP means
"object-oriented", not class-oriented, and nothing in the most basics
definitions of OO [1] requires nor even imply the notion of "class".
This notion is mostly an artifact for easing the definition of a family
of objects having similar implementation, and some 00 languages managed
to get by without classes (look for "prototype-based languages" - the
most known being javascript). wrt/ Python, classes are actually objects
too, and instances have a reference to their class. Since one can
dynamically modify the instance object -class object relation at
runtime, we're quite close to prototype-based languages !-)
[1] "an object is defined by an identity, a state and a behaviour."
Jun 21 '07 #7

P: n/a
On Jun 21, 12:22 am, Bruno Desthuilliers <bruno.
42.desthuilli...@wtf.websiteburo.oops.comwrote:
apolloni...@gmail.com a écrit :
(snip)
>I would like to be able to get a good hold of the concept
state machines ?
Well both state machines and classes (objects). That may be a bit of a
tall order to take on all at once but the concepts seem to be quite
related.

They are, since OO was born from the use of state machines for
simulation (the Simula language). But you can do state machines with a
database and a procedural language too, and FWIW, the "state machine"
aspect of OO is more often very informal and ad hoc.
I already have a great deal of material on Classes so good to
go there.

Don't confuse "classes" with OO. The "OO" in OOP means
"object-oriented", not class-oriented, and nothing in the most basics
definitions of OO [1] requires nor even imply the notion of "class".
This notion is mostly an artifact for easing the definition of a family
of objects having similar implementation, and some 00 languages managed
to get by without classes (look for "prototype-based languages" - the
most known being javascript). wrt/ Python, classes are actually objects
too, and instances have a reference to their class. Since one can
dynamically modify the instance object -class object relation at
runtime, we're quite close to prototype-based languages !-)

[1] "an object is defined by an identity, a state and a behaviour."
No, I realize classes are just a way to represent an object and are
simply a component of the given language. I started dabbling in
programming with C and then started playing with Python (I can see
where classes provide a great deal of power in python). I just want to
get to the point where I can sit down and work out a practical class,
then use it effectively. This discussion has given me a lot to work
with. Thanks!

Jun 21 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.