Re: [Tutor] designing POOP

2008-04-12 Thread bhaaluu
On Sat, Feb 9, 2008 at 9:46 AM, Alan Gauld [EMAIL PROTECTED] wrote:

  As I mentioned in an earlier mail it tends to oscillate in practice.
  You start off looking at the problem to identify the basic classes.
  Then you pick one or two and start designing those in detail and
  that identifies lower level classes. When you reach the point of
  being able to write some code you do so. The act of writing code
  brings up issues that get reflected back up the design - maybe
  even identifying new classes. Once you've written as much
  code as you can you go back up to the problem level, using
  your new found knowledge and design a bit more. Once you
  know enough to start coding go back into code mode again.

  This constant iteration between top level class discovery and low
  level class construction is what Grady Booch refers to in his book
  as Round Trip Gestalt Design and in practice is how most
  software other than the very biggest projects is built.

I recently found the Grady Booch book:
OBJECT ORIENTED DESIGN WITH APPLICATIONS. Benjamin Cummings, 1991.

pg. 189:
As Heinlein suggests, When faced with a problem you do not understand,
do any part of it you do understand, then look at it again. This is just
another way of describing round-trip gestalt design.

pg. 517:
round-trip gestalt design
A style of design that emphasizes the incremental and iterative
development of a system, through the refinement of different yet
consistent logical and physical views of the system as a whole; the
process of object-oriented design is guided by the concepts of
round-trip gestalt design: round-trip gestalt design is a recognition of that
fact that the big picture of a design affects its details, and that the
details often reflect the big picture.

Happy Programming.
-- 
b h a a l u u at g m a i l dot c o m
Kid on Bus: What are you gonna do today, Napoleon?
Napoleon Dynamite: Whatever I feel like I wanna do. Gosh!
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-21 Thread bhaaluu
On Wed, Feb 20, 2008 at 7:53 PM, Alan Gauld [EMAIL PROTECTED] wrote:
 Michael Langford [EMAIL PROTECTED] wrote

   I'm firmly with Kent here: OO programming is not about simulation.

  Wooah!
  I'm partly on board here and do agree the noun/verb thing is
  a gross simplification. But it does work and is how probably
  the majority of OOP programmers started out - in the 80's
  and 90's at least. Certainly when I started on OOP around 1984
  it was the de-facto introduction. And it is a still an effective
  way to identify objects if you aren't sure where to start.

  [snipped for brevity]

   Often it feels like the Model objects on real world objects is how
   people are taught so they get the idea of an object. Actually
   designing all code that way is a needless proscription that really
   really hurts many projects.

  I agree with this too. It has to be emphasised that it's only a
  starting point to identify object candidates, the final solution
  may look very different. But in my experience the bigger the
  project the closer the abstractions get to reality at least at
  the object identity level - the operations and data are likely
  to be very different, and underneath that layer will be a wealth
  of lower level abstractions unguessed at by nouns/verbs.

  But heh, if you get presented with a requirements spec
  of 400 pages and over 1000 user storiers (as I just have!) it's
  as good a place to start as any! (IMHO of course! :-)
  And hopefully no newbies on the tutor list is in any danger
  of that happening to them!

  --
  Alan Gauld
  Author of the Learn to Program web site
  http://www.freenetpages.co.uk/hp/alan.gauld
  Which is currently dead awaiting a server repair, sorry! :-(

Somewhere along the line (in the original thread) the idea of
trying to teach a Beginner how to design an OOP in Python
got lost in a bunch of java mumbo jumbo (at least, that's
what it seemed like to me).

After looking at a lot of stuff, and reading much more than
I needed to, the technique that works best for me is the
noun/verb technique. I think it is a good STARTING point!

Now, I understand that there are many different levels of
beginner. Some beginners are higher up the ladder than
others, and they enjoy looking in windows higher up. However,
I'm still on the bottom rung. The technique that I can relate to
is the noun/verb technique. Does this mean that if I get a grasp
of POOP with this technique that I'll be stuck on the bottom
rung forever? I doubt it. No more than someone who is using
whatever technique they are currently using is stuck with that
technique forever.

The universe unfolds perfectly.
Time exists so it doesn't unfold all at once.

I think the noun/verb technique is good for Absolute beginners.
I haven't seen anything else that is so introductory.

Too bad there isn't a graded tutorial that systematically
uses the technique to build several working PYTHON OOPs.

Happy Programming!
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance. Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-20 Thread Alan Gauld
Michael Langford [EMAIL PROTECTED] wrote

 I'm firmly with Kent here: OO programming is not about simulation.

Wooah!
I'm partly on board here and do agree the noun/verb thing is
a gross simplification. But it does work and is how probably
the majority of OOP programmers started out - in the 80's
and 90's at least. Certainly when I started on OOP around 1984
it was the de-facto introduction. And it is a still an effective
way to identify objects if you aren't sure where to start.

But it is not a good way to model software, with that I
agree. But OOP is still about suimulation. A lot of OOP
code - especially on very large scale projects is as close
a simulation as possible to the real world problem as
you can get. If you are going to work on 5-10 million lines
of code you had better organise it according to some
tangible model you can understand or you will have
problems. Performance and efficiency come a long way
behind comprehensibility at that scale. But on more
normal projects, say 100K-1 million lines then other
factors come to the fore, and flexibility of design is one
big area where OOP techniques can help.

RANT
Unfortunately there seeems to be a lobby at work in OO
these days (indeed in software engineering generally) that
has forgotten about large scale stuff and treats the entire
subject as if it were exclusively about small scale projects.
This is unfortunate because software engineering was
invented to tackle the large scale problems not the
small, and this view also fails to recognise the very different
approaches needed to cover both bases. Here in the
Python community we rarely need to think big, I don't
know of any really large projects being done in Python.
But it is important to remember that topics like OOP
cover all areas.
/RANT

 are not modeling real world items. You are making code easier to
 maintain and making parts of code that have to do with one another 
 be
 near one another.

That's true of any design technique regardless of whether
it is OOP or procedural or even of it's not software at all.
However it's not somerthing that will help a beginner see
objects in their code, especially since the resultant
objects are often of the highly abstract or large grained
variety.

 If you spend all your time trying to make your objects into real 
 world
 things you're actually doing simulation, not programming. As a 
 person
 who's actually done simulation, I'll state that 's not really a 
 great
 way to structure code. You spend a lot of time arguing about highly
 abstract responsibilities of each object in your system, as well as
 how much it will actually model the real world. Neither one is
 especially helpful,

This bit I do agree with. Model the real world to get a feel for
the problem at hand, model the real world as an aid to identifying
potential objects, model the real world while it helps solve the
problem. But don't be a slave to it, you are writing a program to
solve a problem not to model the world. Never forget which is
the tool and which the result.

But OTOH most of the programs I build or design are simulations,
whether of a call centre, a manufacturing plant, a banking system
or a local council, an airport traffic control system or a telephone
switch - and the software invariably reflects that structure.
It does not however model every feature of a PBX, lathe, teller etc
It reflects the attributes of those objects that relate to the 
problem.

 programing. The Why of OO programming today is: To make code more
 maintainable/usable and to group and to use data in such a way the
 human mind can easily grasp all the abstract data types that a 
 program
 operates on.

And the latter point is one area where modelling based on real
world entities can be a big plus. But based on them, not slavishly
reproducing them.

 OO programing came from simulation people. They used a language
 (Simula) to do simulation. It allowed each object to have behavior
 linked to its type.

And it is still used today within the simulation community.
We have a fairly active Simula group at work doingnetwork
analyses.

 Other people saw this (Smalltalk), then copied the system (which 
 they
 were incidentally using to build Smalltalk at first), but not to
 simulate real world objects,

Quite a lot of the early Smalltalk stuff did indeed copy real
world objects but they also saw the potential in modelling
virtual objects like the UI elements. They were using Smalltalk
to teach/experiment with young children by that time and the
correspondence between real objects - like pens - and
computing devices was a beneficial side effect.

 When Bjarne Stroustrup made C++, he copied some of the ideas in 
 order
 to make a better type system, where the functions that operated on a

Yes, although he was actually using the tool to build a simulation.
That's why he started with Simula...

 Object-oriented programming is programming using inheritance.

Nit Pick
I never agreed with Bjarne on that. There are a number 

Re: [Tutor] designing POOP

2008-02-15 Thread Michael Langford
I'm firmly with Kent here: OO programming is not about simulation. You
are not modeling real world items. You are making code easier to
maintain and making parts of code that have to do with one another be
near one another.

If you spend all your time trying to make your objects into real world
things you're actually doing simulation, not programming. As a person
who's actually done simulation, I'll state that 's not really a great
way to structure code. You spend a lot of time arguing about highly
abstract responsibilities of each object in your system, as well as
how much it will actually model the real world. Neither one is
especially helpful, as neither one is addressing the Why of OO
programing. The Why of OO programming today is: To make code more
maintainable/usable and to group and to use data in such a way the
human mind can easily grasp all the abstract data types that a program
operates on.

OO programing came from simulation people. They used a language
(Simula) to do simulation. It allowed each object to have behavior
linked to its type. They were simulating combat and needed to model
the behaviors of all the objects (ships) when they all interacted
together.

Other people saw this (Smalltalk), then copied the system (which they
were incidentally using to build Smalltalk at first), but not to
simulate real world objects, but to instead better group functions
with the data that those functions operate on. Objects could be
created on the fly in there system. They first coined the term Object
Oriented Programming. They real novel thing they did with all of this
was to build the first windowing GUI's and mice into a programming
language. They were not modeling anything in the real world, they were
putting all the components and methods pertaining to building a little
square on the screen into a class, or all the methods pertaining to a
mouse input into a class.

When Bjarne Stroustrup made C++, he copied some of the ideas in order
to make a better type system, where the functions that operated on a
type were put together with the data into an abstract data type by his
preprocessor (C++ was a preprocessor for many years before it was a
compiler). In his own words:

Object-oriented programming is programming using inheritance. Data
abstraction is programming using user-defined types. With few
exceptions, object-oriented programming can and ought to be a superset
of data abstraction.

The key feature of object is *that you make types* (and you put the
methods with the type, as part of the type). That you can do
polymorphism. Etc.

OO is not a glorified simulation system, and you will feel pain if you
overemphasize the generalization Model objects on real world
objects. Objects do have to have an idea (Cohesion). It is just, that
idea doesn't have to be congruous with something you can walk over to
and pick up in the real world.

Often it feels like the Model objects on real world objects is how
people are taught so they get the idea of an object. Actually
designing all code that way is a needless proscription that really
really hurts many projects.

 --Michael

On Fri, Feb 15, 2008 at 8:38 AM, Kent Johnson [EMAIL PROTECTED] wrote:
 Tiger12506 wrote:

   I like things to be explicit, and don't care for the level of
   abstraction common in MVC. I know it seems naive, but I like to be able to
   model object designs after tangible things, and to me, a View does not know
   how to keep a state or execute methods because it does not exist. A
   Controller does not exist alone of the model, and without the view it fails
   to work.

  I agree that this is a naive view, for the same reason I objected to
  Alan's find the nouns approach to OO design. For me considerations of
  cohesion, encapsulation, DRY, testability, and any required reuse or
  flexibility are far more important to design than correspondence with
  tangible objects.

  Kent


 ___
  Tutor maillist  -  Tutor@python.org
  http://mail.python.org/mailman/listinfo/tutor




-- 
Michael Langford
Phone: 404-386-0495
Consulting: http://www.RowdyLabs.com
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-14 Thread Alan Gauld
Tiger12506 [EMAIL PROTECTED] wrote

 Ah yes... I don't like the Model-View-Controller architecture. That 
 the
 major reason why I dislike most information available on C++. This 
 is a
 personal issue though. The Model-View-Controller is a very common 
 thing, and
 everyone but me would be wise to use it. :-)

Now I'm curious.

MVC is one of the oldest, best established and well proven design
patterns going. It first appeared in Smalltalk in the late 1970's and
has been copied in almost every GUI and Web framework ever since.
I've used it on virtually(*) every GUI I've ever built(**) to the 
extent that
I don't even think about it much anymore, therefore:

What do you dislike about it? And what do you use in its place?

(*)The only exceptions were ObjectVision, a strange graphical
Windows app builder from Borland and a weird scripting language for 
the
very early X Windows toolkits(X10), which looked like csh and produced
truly ugly GUIs very quickly. And, of course, native Tcl/Tk has a 
slightly
different model.

(**)Those include GUIs built in Smalltalk, Lisp, TurboPascal, Delphi,
C/C++, ObjectiveC, Java, Python (of course) and even PL/SQL

An alternative perspective is always interesting.

Alan G.



___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-14 Thread Tiger12506
 Now I'm curious.

 MVC is one of the oldest, best established and well proven design
 patterns going. It first appeared in Smalltalk in the late 1970's and
 has been copied in almost every GUI and Web framework ever since.
 I've used it on virtually(*) every GUI I've ever built(**) to the
 extent that
 I don't even think about it much anymore, therefore:

 What do you dislike about it? And what do you use in its place?

I may not be the most newbie around here, but I am certainly very newbish 
compared to you and Kent. That means that I do not have perhaps an adequate 
amount of experience in practical application, but I dislike the concept 
because in every situation that I have encountered so far, it has tripped me 
up. I like things to be explicit, and don't care for the level of 
abstraction common in MVC. I know it seems naive, but I like to be able to 
model object designs after tangible things, and to me, a View does not know 
how to keep a state or execute methods because it does not exist. A 
Controller does not exist alone of the model, and without the view it fails 
to work. Sure it helps tremendously in interchanging code pieces-reusability 
a big issue here, but for my purposes, it just seems extraneous.

Seperating drawing and computations can be/cannot be convenient for me 
depending on the application, (my 'plotting' library is a code reusability 
mess) but in general my style of coding (more procedural) tends to get the 
job done and also tends to cut corners in just enough places to make me feel 
that the application is more efficient with resources.

Asking what I use in its place very neatly makes me blush because I use no 
set model, but tend to mix them at my convenience. Have you noticed that I 
haven't posted code on this list in a long, long time??? Hehe.

At any rate, I had noticed that I stepped past my line of authority and 
experience to the point at which I was significantly less capable to pose as 
an expert, and therefore I wrote everyone but me would be wise to use it. 
My apologies.

 (*)The only exceptions were ObjectVision, a strange graphical
 Windows app builder from Borland and a weird scripting language for
 the
 very early X Windows toolkits(X10), which looked like csh and produced
 truly ugly GUIs very quickly. And, of course, native Tcl/Tk has a
 slightly
 different model.

 (**)Those include GUIs built in Smalltalk, Lisp, TurboPascal, Delphi,
 C/C++, ObjectiveC, Java, Python (of course) and even PL/SQL

 An alternative perspective is always interesting.

 Alan G.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-13 Thread Kent Johnson
Alan Gauld wrote:
 This is fine and dandy but what if we want to find out the 
 current value of a.value without calling inc?
 Thats where hetter/setter/direct access comes into the 
 picture.
 In Java and some other languages the idiomatic thing 
 to do is provide methods prefixed with get/set for each attribute
 
 class Counter(object):
 def __init__(self, initial=0, delta=1):...
 def inc(self)...
 def state(self):...
 def getDelta(self): return self.delta
 def getValue(self): return self.value
 def setValue(self, val): self.value = val
 def setDelta(self, val): self.delta = val
 
 Now this is a lot of typing! It also isn't necessary in Python 
 because Python allows you to access the attributes 
 diectly - direct access.

To amplify and clarify a little:

- Other languages can also give direct access to attributes, this is not 
unique to Python. Java and C++, at least (the languages I know), also 
have a way to *restrict* direct access to attributes which Python does 
not really have.

- There is a good reason for using setters and getters in Java and C++ - 
they have no way to convert an attribute access into a method call. So 
if you start with attribute access and then realize you want to add some 
code to the access, you are stuck - you have to change the interface to 
the class. Python does not have this problem - attribute access can be 
converted to a method call using properties. For this reason, there is 
IMO (and as generally accepted usage) no advantage to using getters  
setters in Python for simple attribute access.

Introduction to properties:
http://personalpages.tds.net/~kent37/kk/8.html

- Python does have a convention for documenting which attributes 
(including methods) are considered part of the public interface and 
which are not. Non-public attribute names are prefixed with _ (single 
underscore). This is a signal to users of the class that the attribute 
is considered an internal implementation detail and to use it at your 
own risk.

This is consistent with the Python philosophy that we're all consenting 
adults here - i.e. that the users of a class don't need to be protected 
from shooting themselves in the foot - it is enough to put a warning 
sign on the gun and the foot :-)

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-13 Thread Kent Johnson
Tiger12506 wrote:
 vg = VideoGame()
 howmany = rand.randint(0,100)
 for i in range(howmany):
   vg.buttonpush()
   print vg.score#Tear open the case (hope you have a screwdriver)
 
 OR
 
 class VideoGame():
   def __init__(self):
 self.score = 0
   def updatedisp():
 print self.score
   def buttonpush():
 self.score += 1
 self.updatedisp()
 
 vg = VideoGame()
 howmany = rand.randint(0,100)
 for i in range(howmany):
   vg.buttonpush()#Let the videogame display your score 
 however it wishes
 
 The second way is preferable for many reasons...

Hmm. Not to me. The second version couples the game state with the 
display. I would rather have

- a Game object that maintains the state of the game and has methods to 
manipulate the state

- a Display object that displays the state of the game

- a Controller object that mediates between user interaction, the Game 
and the Display.

Something like:

class Game(object):
   def __init__(self):
 self.score = 0
   def handleSomethingGood(self):
 self.score += 1

class Display(object):
   def showScore(self, score):
 print score

class Controller(object):
   def __init__(self, game, display):
 self.game = game
 self.display = display
   def handleButton(self):
 self.game.handleSomethingGood()
 self.display.showScore(self.game.score)

Now Game.handleSomethingGood() is decoupled from both the display and 
the actual UI event that signals SomethingGood happened.

This is an example of Model-View-Controller architecture (google it). 
Notice that the Game and Display are now reusable (maybe there are both 
GUI and text interfaces to the game, for example, or versions for 
wxPython and PyQt) and testable independently of each other.

A more advanced design might register the Display as an observer of the 
Game score but I don't want to get into that...

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-12 Thread Alan Gauld
Tiger12506 [EMAIL PROTECTED] wrote

 Well, I don't know if this whole email was of use, but it makes the 
 crux of
 the argument make sense to me.

I thought it was pretty clear.

And it highlights that the choices are like anything else in
the world of engineering - a compromise. And the best compromise
in any given situation might be different from the last time.

Engineering is not an exact science.

Alan G 


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-12 Thread Ricardo Aráoz
To further document some points.
This comes from PEP 8 (http://www.python.org/dev/peps/pep-0008/)
For those who need authority :
Author: Guido van Rossum guido at python.org, Barry Warsaw barry at
python.org


  With this in mind, here are the Pythonic guidelines:

  - Public attributes should have no leading underscores.

  - If your public attribute name collides with a reserved keyword,
append
a single trailing underscore to your attribute name.  This is
preferable to an abbreviation or corrupted spelling.  (However,
notwithstanding this rule, 'cls' is the preferred spelling for any
variable or argument which is known to be a class, especially the
first argument to a class method.)

Note 1: See the argument name recommendation above for class
methods.

  - For simple public data attributes, it is best to expose just the
attribute name, without complicated accessor/mutator methods.
Keep in
mind that Python provides an easy path to future enhancement, should
you find that a simple data attribute needs to grow functional
behavior.  In that case, use properties to hide functional
implementation behind simple data attribute access syntax.

Note 1: Properties only work on new-style classes.

Note 2: Try to keep the functional behavior side-effect free,
although
side-effects such as caching are generally fine.

Note 3: Avoid using properties for computationally expensive
operations; the attribute notation makes the caller believe
that access is (relatively) cheap.

  - If your class is intended to be subclassed, and you have attributes
that you do not want subclasses to use, consider naming them with
double leading underscores and no trailing underscores.  This
invokes
Python's name mangling algorithm, where the name of the class is
mangled into the attribute name.  This helps avoid attribute name
collisions should subclasses inadvertently contain attributes
with the
same name.

Note 1: Note that only the simple class name is used in the mangled
name, so if a subclass chooses both the same class name and
attribute
name, you can still get name collisions.

Note 2: Name mangling can make certain uses, such as debugging and
__getattr__(), less convenient.  However the name mangling algorithm
is well documented and easy to perform manually.

Note 3: Not everyone likes name mangling.  Try to balance the
need to avoid accidental name clashes with potential use by
advanced callers.


HTH
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-12 Thread Ricardo Aráoz
Tiger12506 wrote:
 This is all fine and dandy, but the video game is pretty worthless unless 
 it
 can show us what the score is. There are two ways to go about this. A) 
 Give
 the video game a display which it updates, or B) Tear open the case of 
 the
 video game and look at the actual gears that increment the score to read 
 it.
 Mmmm... that's not really so. If the object's creator meant the score to
 be read that way then it would not be 'Tear open the case' but just
 'read the score'. The language with which we describe an action does 
 matter.
 
 You just invalidated your own argument. Sure, the object's creator may have 
 designated that the way to read the score is to take these screws out and 
 measure the angle of these gears in ratio to those gears

No, the object's creator designed that the way to get the score is to
read it.

 but what are you 
 really doing here?  ...(you are thinking procedurally)... You are really 
 just overlooking the fact that the object is being *read*, meaning that the 
 *object itself  returns a representation*. This tearing apart should be 
 abstracted with a method.

Why? Because you are used to do it that way?

 The meer fact that you say 'tearing open the case' 

YOU are saying it. I'm saying 'read the score'.

 as just another way to say 'read the score' suggests a method called 
 readscore().

Maybe it suggests that to you, not to me. But hey, if it did suggest
readscore() or getscore() then it might also suggest setscore() and then
we might also make sure that score is an integer so we'd better
declare it an integer and have an exception if it is ever used to hold
another type, they we might just see the light and start programming Java.

  You are exactly right. It does not matter with what language 
 you describe an action, because the interface should still remain the same 
 whether you are reading an attribute, or calculating high level summation 
 probabilities to find the score. You are still justvg.readscore()

Nope, I'm just myVar = vg.score
and there are even ways to make sure that when the user of the class
writes that line he receives a high level summation probability just
as if he'd called a method, remember this is Python.

 
 Your particular issue is with the simplicity of the attribute, we don't need 
 a getter method. True. But that in agreement with the concept of OOP.

Sorry, which concept? According to whom?

 If you 
 decide to pick and choose whether an object does it or whether the developer 
 does it, not only do you have inconsistency in your programming style, but 
 you are no longer OBJECT-Oriented.

Says who?
Anyway, I'm no theoretician, I'm a mere programmer. We programmers deal
with practical things so I don't really care if I'm in or out of your
concept of object orientation. So long as my code is maintainable,
extendable, and does what it's supposed to do I'm ok with it, object or
non-object oriented.
Anyway if you wish for better people than me to expose this to you I
suggest you address the python-list ([EMAIL PROTECTED]) and post a
message saying We should access properties through setters and getters,
otherwise it is not TRUE OOP. I won't take responsibility for any flames.

 PS This is one of the big issues that developers have with the win32api. It 
 is procedural in this section, OOP in this section, etc. and more time is 
 spent actually look up these subtle differences to prevent errors than is 
 used in actual coding. A perfect OOP library does not Need a reference book. 
 A good OOP library should only need to propose a pattern.

I like good references, I like good documentation. But hey, different
strokes...

 The second way is preferable for many reasons...
 A) The game designer decides to change the display, you don't have to 
 change
 any code that uses the class
 B) Clearly, tearing open a videogame is pretty low-level from an object
 perspective. This is what Alan is saying with OOP purism.

 Did we think about REUSABILITY? What if in some other application I want
 to USE the score, not just display it? What if I want to display it in a
 different form (multiplying it by 100)? Then you are back to our
 original options : either check the score directly, define a getter, or
 a  'stater'(?) which returns the state of the object (in this case
 it would be a tuple with only the score in it, a getter in disguise if
 you ask me). AFAIK the python way is to just check the score, if later
 the object's author changes something he has ways built in in the
 language to keep the interface unchanged (yes, I think the score would
 be part of the interface, otherwise it would be _score).
 
 I completely disagree with your issue on REUSABILITY here. Are you familiar 
 with the concept of subclassing?

So if I subclass the class it's ok to mess with the property but if I
use the class it's not? Why should that be so? What advantage would that
give me?
If I subclass it, then declare a getter that reads the property and

Re: [Tutor] designing POOP

2008-02-12 Thread Tiger12506
 This is all fine and dandy, but the video game is pretty worthless unless 
 it
 can show us what the score is. There are two ways to go about this. A) 
 Give
 the video game a display which it updates, or B) Tear open the case of 
 the
 video game and look at the actual gears that increment the score to read 
 it.

 Mmmm... that's not really so. If the object's creator meant the score to
 be read that way then it would not be 'Tear open the case' but just
 'read the score'. The language with which we describe an action does 
 matter.

You just invalidated your own argument. Sure, the object's creator may have 
designated that the way to read the score is to take these screws out and 
measure the angle of these gears in ratio to those gears but what are you 
really doing here?  ...(you are thinking procedurally)... You are really 
just overlooking the fact that the object is being *read*, meaning that the 
*object itself  returns a representation*. This tearing apart should be 
abstracted with a method. The meer fact that you say 'tearing open the case' 
as just another way to say 'read the score' suggests a method called 
readscore().  You are exactly right. It does not matter with what language 
you describe an action, because the interface should still remain the same 
whether you are reading an attribute, or calculating high level summation 
probabilities to find the score. You are still justvg.readscore()

Your particular issue is with the simplicity of the attribute, we don't need 
a getter method. True. But that in agreement with the concept of OOP. If you 
decide to pick and choose whether an object does it or whether the developer 
does it, not only do you have inconsistency in your programming style, but 
you are no longer OBJECT-Oriented.

PS This is one of the big issues that developers have with the win32api. It 
is procedural in this section, OOP in this section, etc. and more time is 
spent actually look up these subtle differences to prevent errors than is 
used in actual coding. A perfect OOP library does not Need a reference book. 
A good OOP library should only need to propose a pattern.


 The second way is preferable for many reasons...
 A) The game designer decides to change the display, you don't have to 
 change
 any code that uses the class
 B) Clearly, tearing open a videogame is pretty low-level from an object
 perspective. This is what Alan is saying with OOP purism.


 Did we think about REUSABILITY? What if in some other application I want
 to USE the score, not just display it? What if I want to display it in a
 different form (multiplying it by 100)? Then you are back to our
 original options : either check the score directly, define a getter, or
 a  'stater'(?) which returns the state of the object (in this case
 it would be a tuple with only the score in it, a getter in disguise if
 you ask me). AFAIK the python way is to just check the score, if later
 the object's author changes something he has ways built in in the
 language to keep the interface unchanged (yes, I think the score would
 be part of the interface, otherwise it would be _score).

I completely disagree with your issue on REUSABILITY here. Are you familiar 
with the concept of subclassing? Or if you wish to ignore the power of OOP, 
you can just add another method, which is still more realistic and intuitive 
than directly accessing an internal state variable. Perhaps your major issue 
here is whether or not score should be public? Alright. Give me one instance 
in daily usage of any video game where the score of a video game is changed 
without the video game knowing it. (example - cosmic rays change a bit in 
the storage of the score and the video game is not aware of it) This concept 
would allow a violation of a pure OOP VideoGame class, and allow an 
otherwise private internal state to be made public.


PS - for fun. I can think of a more common reason why the score of video 
games would change without using the actual video game interface. I watched 
a tv episode of masterminds where the criminal thought up the perfect plan 
to trick a slot machine by directly accessing the physical chip that 
determined a winning combination. If the developer of the slot machine had 
wanted this to be the way that winning combinations are chosen, he should 
have provided a method which allowed for this. 

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-12 Thread bhaaluu
On Feb 12, 2008 7:19 AM, Ricardo Aráoz [EMAIL PROTECTED] wrote:

 Did we think about REUSABILITY? What if in some other application I want
 to USE the score, not just display it? What if I want to display it in a
 different form (multiplying it by 100)? Then you are back to our
 original options : either check the score directly, define a getter, or
 a  'stater'(?) which returns the state of the object (in this case
 it would be a tuple with only the score in it, a getter in disguise if
 you ask me). AFAIK the python way is to just check the score, if later
 the object's author changes something he has ways built in in the
 language to keep the interface unchanged (yes, I think the score would
 be part of the interface, otherwise it would be _score).


Everything in this discussion seems relevant to designing Python OOP.
(Python is not java, not javascript, not c++, not visual whatever etc.)
We can see from this that Python does it the Python way. The Java examples
are pretty much wasted on me. (I don't know anything about Java at all.)

The POOP tutorials rarely get into design considerations. They introduce
the mechanics of making a program, make a sample program, and keep
on trucking.  I'm trying to learn how to design a program with Python.

So far, two beginner techniques have been shown: the noun/verb/adjective
method (Alan), and the TDD (Test Driven Design) method (Kent). Of the two,
the noun/verb/adjective method seems more approachable (to me). I think
that once I have some experience doing that, then the TDD method may have
something to offer.

Baby steps first. Walk before running. 8^D
Happy Programming!
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-12 Thread Ricardo Aráoz
Tiger12506 wrote:

 This is all fine and dandy, but the video game is pretty worthless unless it 
 can show us what the score is. There are two ways to go about this. A) Give 
 the video game a display which it updates, or B) Tear open the case of the 
 video game and look at the actual gears that increment the score to read it. 

Mmmm... that's not really so. If the object's creator meant the score to
be read that way then it would not be 'Tear open the case' but just
'read the score'. The language with which we describe an action does matter.

 
 vg = VideoGame()
 howmany = rand.randint(0,100)
 for i in range(howmany):
   vg.buttonpush()
   print vg.score#Tear open the case (hope you have a screwdriver)
 
 OR
 
 class VideoGame():
   def __init__(self):
 self.score = 0
   def updatedisp():
 print self.score
   def buttonpush():
 self.score += 1
 self.updatedisp()
 
 vg = VideoGame()
 howmany = rand.randint(0,100)
 for i in range(howmany):
   vg.buttonpush()#Let the videogame display your score 
 however it wishes
 
 The second way is preferable for many reasons...
 A) The game designer decides to change the display, you don't have to change 
 any code that uses the class
 B) Clearly, tearing open a videogame is pretty low-level from an object 
 perspective. This is what Alan is saying with OOP purism.
 

Did we think about REUSABILITY? What if in some other application I want
to USE the score, not just display it? What if I want to display it in a
different form (multiplying it by 100)? Then you are back to our
original options : either check the score directly, define a getter, or
a  'stater'(?) which returns the state of the object (in this case
it would be a tuple with only the score in it, a getter in disguise if
you ask me). AFAIK the python way is to just check the score, if later
the object's author changes something he has ways built in in the
language to keep the interface unchanged (yes, I think the score would
be part of the interface, otherwise it would be _score).




___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-12 Thread Ricardo Aráoz
Tiger12506 wrote:

 This is all fine and dandy, but the video game is pretty worthless unless it 
 can show us what the score is. There are two ways to go about this. A) Give 
 the video game a display which it updates, or B) Tear open the case of the 
 video game and look at the actual gears that increment the score to read it. 

Mmmm... that's not really so. If the object's creator meant the score to
be read that way then it would not be 'Tear open the case' but just
'read the score'. The language with which we describe an action does matter.

 
 vg = VideoGame()
 howmany = rand.randint(0,100)
 for i in range(howmany):
   vg.buttonpush()
   print vg.score#Tear open the case (hope you have a screwdriver)
 
 OR
 
 class VideoGame():
   def __init__(self):
 self.score = 0
   def updatedisp():
 print self.score
   def buttonpush():
 self.score += 1
 self.updatedisp()
 
 vg = VideoGame()
 howmany = rand.randint(0,100)
 for i in range(howmany):
   vg.buttonpush()#Let the videogame display your score 
 however it wishes
 
 The second way is preferable for many reasons...
 A) The game designer decides to change the display, you don't have to change 
 any code that uses the class
 B) Clearly, tearing open a videogame is pretty low-level from an object 
 perspective. This is what Alan is saying with OOP purism.
 

Did we think about REUSABILITY? What if in some other application I want
to USE the score, not just display it? What if I want to display it in a
different form (multiplying it by 100)? Then you are back to our
original options : either check the score directly, define a getter, or
a  'stater'(?) which returns the state of the object (in this case
it would be a tuple with only the score in it, a getter in disguise if
you ask me). AFAIK the python way is to just check the score, if later
the object's author changes something he has ways built in in the
language to keep the interface unchanged (yes, I think the score would
be part of the interface, otherwise it would be _score).



___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-11 Thread Alan Gauld
bhaaluu [EMAIL PROTECTED] wrote

 States, getters-setters, direct access...
 I'm still in toilet-training here/ 8^D
 Can you provide some simple examples that
 illustrate exactly what and why there is any
 contention at all?

I'll try.

State is just a bit of jargon to describe the combined 
values of an objects attributes. Here is an example:

class Counter(object):
def __init__(self, initial=0, delta=1):
 self.value = initial
 self.delta = delta
def inc(self)
 self.value += delta
 return self.value
def state(self):
 return (self.value,self.delta)

a = Counter()
b = Counter(1)
c = Counter(0,5)

print a.state, b.state, c.state

So all 3 objects have different combinations of values 
so they have different states.
The state determines the value returned by the objects 
inc method

x = a.inc() # x- 1
y = b.inc() # y - 2
z = c.inc() # z - 5

This is fine and dandy but what if we want to find out the 
current value of a.value without calling inc?
Thats where hetter/setter/direct access comes into the 
picture.
In Java and some other languages the idiomatic thing 
to do is provide methods prefixed with get/set for each attribute

class Counter(object):
def __init__(self, initial=0, delta=1):...
def inc(self)...
def state(self):...
def getDelta(self): return self.delta
def getValue(self): return self.value
def setValue(self, val): self.value = val
def setDelta(self, val): self.delta = val

Now this is a lot of typing! It also isn't necessary in Python 
because Python allows you to access the attributes 
diectly - direct access. Like so:

a.delta = 42
a.inc()
print a.value

This gives rise to a debate between the OOP purists who say 
that you should only access the internals of an object via a 
method(get/set) and the pragmatists who say its OK to use 
direct access. And old school OOPers like me say it would 
be better if you didn't need to use either since you should 
define the object in terms of higher level abstractions/methods.

Now, with my pragmatic hat on I see no point whatsoever in 
writing reams of get/set code just for the salke of it, so if you 
must bypass the abstract methods use direct access. But 
what if you want all of the attributes - to print state say?
Thats where the question of direct  access versus a state() 
method comes in. My preference is to provide a single 
method that returns the values that you need (and in many 
cases thats less than all of the attributes!) rather than allowing, 
or even encouraging, direct access.

The danger with direct access is that we use it not only for 
reading but also for directly modifying the attributes - and 
that is a bad OOP habit! (Remember: Objects do it to themselves!) 
For example we want to decrement a counter instead of 
incrementing.

we could do it directly:

c.value = c.value -5

But it would be better to do it in an OOP way.

So the final issue (and Kent will no doubt have more to add 
from his perspective!) is if we do want to modify the Counter 
how do we do it (assuming we don't own the original class 
or too many other projects already use it to risk breaking 
them)? Well, the pure OOP way is by sub classing. 
Thus if we want a counter with a dec() method as well as an 
inc(), we can create one:

class UpDownCounter(Counter):
  def dec(self):
  self.value -= self.delta
  return self.value

Now if we make c an instance of UpDownCounter we can do:

c = UpDownCounter(0,5)
c.inc()
print c.state()
c.dec()
print c.state()

And this has the advantage that there is no impact on the 
other objects derived from the initial Counter class. Note that 
as well as adding methods you can also modify, or change 
entirely, the existing methods, that's called overriding a method 
and is probably left for later!

I hope that makes sense, its about the simplest example 
I could come up with.

-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-11 Thread Tiger12506
 bhaaluu [EMAIL PROTECTED] wrote

 States, getters-setters, direct access...
 I'm still in toilet-training here/ 8^D
 Can you provide some simple examples that
 illustrate exactly what and why there is any
 contention at all?

One clear example I can think of that shows the views is this:

Imagine you have a video game. You model it with a class.

class VideoGame:
  pass

But this video game will up your score if you hit this a particular button, 
which means that it needs to a) keep track of its score b) know what to do 
when the button is pushed

class VideoGame:
  def __init__(self):
self.score = 0
  def buttonpush(self):
self.score += 1

This is all fine and dandy, but the video game is pretty worthless unless it 
can show us what the score is. There are two ways to go about this. A) Give 
the video game a display which it updates, or B) Tear open the case of the 
video game and look at the actual gears that increment the score to read it. 
(imagine it's an old, old game - work with me here!)
So, to print, you can...

vg = VideoGame()
howmany = rand.randint(0,100)
for i in range(howmany):
  vg.buttonpush()
  print vg.score#Tear open the case (hope you have a screwdriver)

OR

class VideoGame():
  def __init__(self):
self.score = 0
  def updatedisp():
print self.score
  def buttonpush():
self.score += 1
self.updatedisp()

vg = VideoGame()
howmany = rand.randint(0,100)
for i in range(howmany):
  vg.buttonpush()#Let the videogame display your score 
however it wishes

The second way is preferable for many reasons...
A) The game designer decides to change the display, you don't have to change 
any code that uses the class
B) Clearly, tearing open a videogame is pretty low-level from an object 
perspective. This is what Alan is saying with OOP purism.

Now. Alan's suggestion to have a state method is like... having a sticker on 
the side of the video game that constantly changes to show the internal 
state of the machine. (yeah yeah, stickers change, sure...) Anyway, This is 
very nice from a debugging standpoint, where you find out that the game does 
something incredibly weird, (like after 2**16 buttonpushes it jumps to 
negative numbers), so that you can watch exactly what happens inside the 
machine without tearing it apart. There are a few drawbacks though.
As soon as you change the internal mechanism, the sticker is at a loss 
because it can't tell you the state anymore! So every time you change the 
internals, you have to change the sticker on the outside to reflect that 
change. This is what Kent is trying to say here about the lack of advantage 
to a state method. However, the advantage of pure OOP here is that if the 
videogame model is designed correctly, never would you have to change the 
actual display if you changed how the score was calculated.

Well, I don't know if this whole email was of use, but it makes the crux of 
the argument make sense to me. 

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-11 Thread Alan Gauld
Kent Johnson [EMAIL PROTECTED] wrote

 The secondary reason is that a class author should be free
 to change the internal data of a class provided he doesn't change
 the message interface, but allowing direct access greatly increases
 the risk that a change will break some users code. Particularly
 if the change involves removing an attribute or converting it to a
 derived value.

 That is the usual argument for getters and setters in Java and C++ 
 (at
 least). It makes sense for those languages but it doesn't hold water 
 in
 Python where a simple attribute can be changed to a property with
 whatever underlying functionality you like and no change in client 
 code.

While that's true, it does move the onus onto the class maintainer
to develop backwards compatible properties that may no longer
have any releavance to the internal method code. For example
a circle shape which moves from using a centre+radius system
to one which uses a bounding box, or vice versa. (Although it could
be argued that regardless of the implementation the radius/centre
should be properties of the circle)

But more dangerous is a database access class that stores the
tablename and then changes database schema such that two
names are needed, or vice versa, and direct access to that kind
of attribute would be a very bad smell indeed! Why does the client
need the tablename?!

I think we are in general agreement, albeit with different levels of
trust/toleration of the technique. Direct access is preferred to
getter/setter methods but is in turn less desirable that higher
level methods where they exist. The only contention seems to be
whether a values() type mutilple-return method is worth anything over
direct access. My personal taste is that if I need the entire 
official
state of an object I'd like a method to give it me in one piece, but
others obviously may feel differently.

-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld 


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-11 Thread bhaaluu
On Feb 11, 2008 3:49 AM, Alan Gauld [EMAIL PROTECTED] wrote:

 I think we are in general agreement, albeit with different levels of
 trust/toleration of the technique. Direct access is preferred to
 getter/setter methods but is in turn less desirable that higher
 level methods where they exist. The only contention seems to be
 whether a values() type mutilple-return method is worth anything over
 direct access. My personal taste is that if I need the entire
 official
 state of an object I'd like a method to give it me in one piece, but
 others obviously may feel differently.

 --
 Alan Gauld
 Author of the Learn to Program web site
 http://www.freenetpages.co.uk/hp/alan.gauld

States, getters-setters, direct access...
I'm still in toilet-training here/ 8^D
Can you provide some simple examples that
illustrate exactly what and why there is any
contention at all?

TIA
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-10 Thread Dave Kuhlman
On Sat, Feb 09, 2008 at 08:42:04PM -0500, Kent Johnson wrote:
 Alan Gauld wrote:
 
def values(self):
  return (self.name, self.wealth, self.strenth)
 
  Or get rid of values() entirely and just refer to the attributes
  
  Nope, I don't like that as much since it encourages direct
  access. 
 
 Maybe we just need to agree to disagree here. I don't see how returning 
 a tuple is better encapsulation than direct access to named attributes.

Here is something relevant to this argument, although I'm not sure
that I agree with it:

Getters and setters are evil. Evil, evil, I say! Python objects
are not Java beans. Do not write getters and setters. This is
what the 'property' built-in is for. And do not take that to
mean that you should write getters and setters, and then wrap
them in 'property'. That means that until you prove that you
need anything more than a simple attribute access, don't write
getters and setters. They are a waste of CPU time, but more
important, they are a waste of programmer time. Not just for
the people writing the code and tests, but for the people who
have to read and understand them as well.

In Java, you have to use getters and setters because using
public fields gives you no opportunity to go back and change
your mind later to using getters and setters. So in Java, you
might as well get the chore out of the way up front. In Python,
this is silly, because you can start with a normal attribute
and change your mind at any time, without affecting any clients
of the class. So, don't write getters and setters.

   extracted from:
  http://dirtsimple.org/2004/12/python-is-not-java.html

Maybe I'm old school, but I still use getters and setters for
access from outside the class and direct access from within methods
in the class.

- Dave

[some good arguments snipped]


-- 
Dave Kuhlman
http://www.rexx.com/~dkuhlman
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-10 Thread Alan Gauld
Kent Johnson [EMAIL PROTECTED] wrote

 Alan doesn't like direct attribute access *or* getters and setters,
 IIUC. He wants all access to the attributes of a class instance to 
 be
 through higher-level methods.

I'd moderate that slightly.
I really, really, don't like getters/setters. So, if you really need 
to
get at an attribute then use direct access.

However if a real responsibility of the class is to present it's
overall state then I prefer to have a method to do that with state
returned as a whole. For small numbers of attributes that could
be a tuple or for longer sets of data as a dictionary.

Over-use of direct access tends, in my experience, to lead to
the temptation to move code that should be in the class (or a
subclass) into client code. And it is avoidance of that temptation
that is my main reason for providing a values() or state() type
method, rather than using multiple attribute access.

The secondary reason is that a class author should be free
to change the internal data of a class provided he doesn't change
the message interface, but allowing direct access greatly increases
the risk that a change will break some users code. Particularly
if the change involves removing an attribute or converting it to a
derived value.

Of course, as Kent pointed out if you add attributes then
you have the question of whether to modify the state() method
too, which also breaks client code - another reason state()
methods should only return those attributes really needed by
the clients!. They are less likely to change.

 I think it is a good goal and technique to look for higher-level
 methods, and to create classes that are amenable to same, but that 
 on a
 practical level attribute access works and I don't avoid it on 
 principle.

I prefer it to getter/setter but try to avoid it if possible.
Pragmatism means that sometimes its useful or even necessary,
but I always question why I'm doing it and whether I should
instead be adding a method or subclassing.

And to close, the reason I made it an issue in this thread is that
this is about a beginner learning good (P)OOP practice so I
thought it would be good to highlight that direct access
carries risk and is frowned on from a purist OOP perspective

Hopefully this side discussion has done that :-)


-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld




 Kent
 ___
 Tutor maillist  -  Tutor@python.org
 http://mail.python.org/mailman/listinfo/tutor
 


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-10 Thread Kent Johnson
Alan Gauld wrote:

 Over-use of direct access tends, in my experience, to lead to
 the temptation to move code that should be in the class (or a
 subclass) into client code. And it is avoidance of that temptation
 that is my main reason for providing a values() or state() type
 method, rather than using multiple attribute access.

I agree that it is easy to write code in a client, using attribute 
access, that really should be in the class as a method. I'm not sure how 
providing a value() method prevents that, other than making the client 
code more awkward.

In either case the solution is to recognize the code smell (Feature Envy 
or Inappropriate Intimacy) and refactor to fix the problem.

 The secondary reason is that a class author should be free
 to change the internal data of a class provided he doesn't change
 the message interface, but allowing direct access greatly increases
 the risk that a change will break some users code. Particularly
 if the change involves removing an attribute or converting it to a
 derived value.

That is the usual argument for getters and setters in Java and C++ (at 
least). It makes sense for those languages but it doesn't hold water in 
Python where a simple attribute can be changed to a property with 
whatever underlying functionality you like and no change in client code.
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-09 Thread Alan Gauld

Tiger12506 [EMAIL PROTECTED] wrote

 Are some simple examples off the top of my head. It's not difficult 
 to model
 real-life things with classes, but ...

This is a good point, it is excellent practice for thinking
about the responsibilities of objects

 ...it is much more difficult to model them
 in such a way that you interact with them normally.

And this is the bit that does require experience and careful thought.
But even thinking in the absract about doors, knobs,locks etc helps
to get the brain attuned to the kind of decions that need to be made

 door, or the knob? Does the knob contain a Lock, or does the 
 developer only
 need to know that it has one and whether it is locked or not?)

And its important to remember that the answers will be problem 
dependant.
There is no absolute right or wrong, just what works best for your 
problem.

Of course that's why building reusable objects is so hard.
Something apparently reusable will usually only be reusable
within a single problem domain. And even then may need to
be tweaked for the specific problem. It has been estimated
that building reusable objects costs between 3-5 times as
much as building a bespoke version (and commercially
reusable objects cost up to 10 times as much!)

Alan G. 


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-09 Thread bhaaluu
On Feb 9, 2008 4:09 AM, Alan Gauld [EMAIL PROTECTED] wrote:

 Tiger12506 [EMAIL PROTECTED] wrote

  Are some simple examples off the top of my head. It's not difficult
  to model
  real-life things with classes, but ...

 This is a good point, it is excellent practice for thinking
 about the responsibilities of objects

  ...it is much more difficult to model them
  in such a way that you interact with them normally.

 And this is the bit that does require experience and careful thought.
 But even thinking in the absract about doors, knobs,locks etc helps
 to get the brain attuned to the kind of decions that need to be made

I'm really getting a lot out of this discussion. In my tutorial (PPftAB2E)
the second chapter deals with a Blackjack game. One thing I noticed
(and remember, this is a Noob's viewpoint): The classes seemed to be
designed from small to large, rather than from large to small. First,
a card class was made that had card-object stuff in it (suits and ranks).
Then a hand class was made that inherited the card class. Then, a deck
class was made, that inherited from the hands class (that already had
inherited from the card class). Is this the way you think about designing
classes (small to large). I don't know the proper terminolgy for that yet.

I'm almost ready to start working on another aspect of the adventure game.
I've noticed in my tutorial that several small programs introduce various
classes as the chapter proceeds, then at the end, it is all used to make
the final program. That's fine for the book: no telling how long, or what he
had to do to get it to work that way. But I'm just trying to figure out the
design of the adventure game in small increments. If, in the end, I can
use parts of these small programs to make the final program, great!
But for now, I'm trying to keep it at a manageable size while I'm learning.

There is a castle which has several levels and each level has rooms on it.
The rooms have doors. The doors connect the rooms to each other. Each
room can have either nothing in it, a treasure, or a monster. Each room
has a description which describes 1) Is there a treasure in the room? (and
if so, what is the amount), 2) Is there a monster in it (and if so, what is the
Danger Level), 3) The room description, including where the doors are,
(N,S,E,W,U,D).

I'd like to try and design this small part so that the Explorer can move
around the environment, from room to room, level to level. That's it.
The Explorer will be able to see, but not pick-up treasure (keeping in
mind that treasure can be picked-up in the final game). The Explorer
will be warned about a monster in the room (keeping in mind that the
monster can be fought in the final game).

Design in small chucks. The Castle needs to be setup. Can the Travel
Table from the procedural game be used? Setup requires that the
floorplan, or map of the castle be used to define each room on a level,
all the doors for the rooms, and treasure/terror. One array is used in
the procedural program. Whoops! Sorry. I'm not supposed to think
about it like that!

If I use the small to large approach: A door is the smallest part of a
room. Each room shares doors. Each floor has rooms. All the floors
are in the Castle.

But in this game, all the doors do is connect the rooms. They don't
have knobs or locks. They don't open or close. (Although they MAY
have that ability in some future game?). My thought is you can't
possibly think of all the future things an object can do or be, but
if the class is designed in a very abstract way, then it will be easier
to add a new behavior or characteristic in the future, if needed?
This is what I'm trying to learn with this adventure game exercise.

So, I'm thinking that a door class isn't necessary? The next thing
is a room. A room has doors that connect to other rooms, a
description, and may contain a monster or treasure. This sounds
like a candidate for a class?

The castle has levels. Each level has rooms. Everything happens
in the castle. The equivalent of the castle in the card game would
be the deck of cards. But the deck of cards holds hands (rooms?)
which are shuffled and dealt to people. It does something. What does
the castle DO? It holds rooms, and monsters and treasure is shuffled
and dealt to random rooms (for the Explorer to find).

Not having much experience doing this, makes it harder than it
should be! What is your thought process on this?


  door, or the knob? Does the knob contain a Lock, or does the
  developer only
  need to know that it has one and whether it is locked or not?)

 And its important to remember that the answers will be problem
 dependant.
 There is no absolute right or wrong, just what works best for your
 problem.

 Of course that's why building reusable objects is so hard.
 Something apparently reusable will usually only be reusable
 within a single problem domain. And even then may need to
 be tweaked for the specific problem. It has been estimated
 that 

Re: [Tutor] designing POOP

2008-02-09 Thread Alan Gauld
bhaaluu [EMAIL PROTECTED] wrote

 the second chapter deals with a Blackjack game. One thing I noticed
 (and remember, this is a Noob's viewpoint): The classes seemed to be
 designed from small to large, rather than from large to small.

As I mentioned in an earlier mail it tends to oscillate in practice.
You start off looking at the problem to identify the basic classes.
Then you pick one or two and start designing those in detail and
that identifies lower level classes. When you reach the point of
being able to write some code you do so. The act of writing code
brings up issues that get reflected back up the design - maybe
even identifying new classes. Once you've written as much
code as you can you go back up to the problem level, using
your new found knowledge and design a bit more. Once you
know enough to start coding go back into code mode again.

This constant iteration between top level class discovery and low
level class construction is what Grady Booch refers to in his book
as Round Trip Gestalt Design and in practice is how most
software other than the very biggest projects is built.

 I've noticed in my tutorial that several small programs introduce 
 various
 classes as the chapter proceeds, then at the end, it is all used to 
 make
 the final program. That's fine for the book: no telling how long, or 
 what he
 had to do to get it to work that way.

One of the problems of tutorials (my own included) is that you
tend to focus on the code and never get round to explaining
to the student how you worked out which classes to build
in the first place! I tried to address that in the Games Framwork
case syudy in the paper book version (try your local library)
which deliberately sets out to create a class Framework step
by step. But its quite hard to explain design techniques at the
very early stages of programming. Thats why some of the
design books I mentioed earlier are good (especially Booch)
because they discuss the process of discovering classes and
objects in the first place, and provide some basic heuristics to
help.

 There is a castle which has several levels and each level has rooms 
 on it.
 The rooms have doors. The doors connect the rooms to each other. 
 Each
 room can have either nothing in it, a treasure, or a monster. Each 
 room
 has a description which describes 1) Is there a treasure in the 
 room? (and
 if so, what is the amount), 2) Is there a monster in it (and if so, 
 what is the
 Danger Level), 3) The room description, including where the doors 
 are,
 (N,S,E,W,U,D).

 I'd like to try and design this small part so that the Explorer can 
 move
 around the environment, from room to room, level to level. That's 
 it.
 The Explorer will be able to see, but not pick-up treasure (keeping 
 in
 mind that treasure can be picked-up in the final game). The Explorer
 will be warned about a monster in the room (keeping in mind that the
 monster can be fought in the final game).

Thats fine so you probably can start with a single room and your
Explorer. Get the explorer to ask the room whats in it and then
the Explorer can tell the Game what it has found.

 import room,explorer
 fred = Explorer('fred')
 room1 = Room(Dragon(),GoldRing(),Bread()
 room2 = Room(Serpent(),Bracelet(),Butter()
 fred.explore(room1)
 fred.describe()
I am in a room with a dragon, a gold ring and a loaf od bread
 fred.explore(room2)
 fred.describe()
I am in a room with a serpent, a bracelet and a pack of butter


Once you have that working its a short step to make the
castle contain a list of rooms with linkages between - possibly
using a variant of your procedural table, but with Room objects
rather than the raw data. The Room initialisation could read
a data file to get the contents of each room...
And the castle initialisation could read the data file to get
the layout of the rooms - sounds like a job for the Python
config file module maybe?

And hppefully from the codec above you can start to think
about what the expore method looks like inside? And maybe
what method the room might need to support that?

 Design in small chucks. The Castle needs to be setup. Can the Travel
 Table from the procedural game be used? Setup requires that the
 floorplan, or map of the castle be used to define each room on a 
 level,
 all the doors for the rooms, and treasure/terror. One array is used 
 in
 the procedural program. Whoops! Sorry. I'm not supposed to think
 about it like that!

No, thinking like that is fine when you are thinking about how
the methods inside the classes work. So long as the castle
stays concerned only with the layout of the rooms (how they
are connected to each other) and the rooms look after the
content within themselves. The Game class will then control the
movement and action of the explorer. So if the user wants the
explorer to go Siouth the Game can ask the Castle which room
(if any) is Sourth of the current Room - and the explorer knows
which room he is currently in so the Game can ask him that,

Re: [Tutor] designing POOP

2008-02-09 Thread bhaaluu
On Feb 9, 2008 8:46 AM, Alan Gauld [EMAIL PROTECTED] wrote:
 bhaaluu [EMAIL PROTECTED] wrote


Some more thoughts on designing here.

You said I can use the procedural program as a program requirement
because it defines I/O. Even though the OOP program will have the
data and functions in classes, I'd like to have the finished program
be identical to the procedural program as far as I/O goes.

So the first little program's I/O looks like this:

WHAT IS YOUR NAME, EXPLORER? _   - first prompt

clrscr()

ZORK, YOUR STRENGTH IS 100
YOU HAVE $  75
IT IS TOO DARK TO SEE ANYTHING

WHAT DO YOU WANT TO DO? _   - second prompt (main game)

So I should be able to 'reuse' some of the code from the first little
program, in the second little program where the castle is setup,
and the player can move around the castle.

IT IS TOO DARK TO SEE ANYTHING is replaced with the room
description, as far as I/O goes, and I'd like for my second little
sample program to follow suit.

When you're designing a program, how do you go about dealing
with text descriptions, like the descriptions for a room? Here is an
example of a room description:

THIS IS THE AUDIENCE CHAMBER
THERE IS A WINDOW TO THE WEST. BY LOOKING TO THE RIGHT
THROUGH IT YOU CAN SEE THE ENTRANCE TO THE CASTLE.
DOORS LEAVE THIS ROOM TO THE NORTH, EAST AND SOUTH.

In the procedural program, it is a function that prints the description:
def room2(): print

The player reads the description, and presses W. There is no west door.
The program's output is:

YOU CANNOT MOVE THROUGH SOLID STONE

and back to the main prompt. Pressing S moves the player through
the South door into another room, where the status of the player is
displayed, and the description of the new room.

The data.py file, with the room descriptions is the biggest file in the
procedural program. I've been told that a data class with a lot of random
data in it is a CodeSmell. Is a data class that has room descriptions in
it, with a function for each room, considered a bad design?

And, since the setup table and the function that decides which room
description is closely related, couldn't they also be a part of that data
class? Is a data class a CodeSmell when all the functions are related?

Or, should I have a room class that can instantiate 19 room objects
which simply accesses the room functions from the data.py file as
it is?

As a side note: Really, the adventure game isn't too much different
from the Bank Account program in your tutorial:: there are several
accounts in the adventure game which are credited and debited
as the game progresses. Pick up treasure: credit my wealth account.
Fight a monster: debit strength account. Move from room to
room: debit strength account. Eat food: credit wealth account.
Buy a weapon: debit wealth account. The real difference between
the two is: moving about the castle and exploring in the adventure
game. In the Bank Account, you are pretty much in one room. You
enter the bank, and leave the bank after taking care of business.

Note: I haven't tried your code snippet below yet, so please keep that
in mind. I may have other thoughts after I try it. These are just some
things I thought about while reading your reply. I don't have any comments
below.
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]

  the second chapter deals with a Blackjack game. One thing I noticed
  (and remember, this is a Noob's viewpoint): The classes seemed to be
  designed from small to large, rather than from large to small.

 As I mentioned in an earlier mail it tends to oscillate in practice.
 You start off looking at the problem to identify the basic classes.
 Then you pick one or two and start designing those in detail and
 that identifies lower level classes. When you reach the point of
 being able to write some code you do so. The act of writing code
 brings up issues that get reflected back up the design - maybe
 even identifying new classes. Once you've written as much
 code as you can you go back up to the problem level, using
 your new found knowledge and design a bit more. Once you
 know enough to start coding go back into code mode again.

 This constant iteration between top level class discovery and low
 level class construction is what Grady Booch refers to in his book
 as Round Trip Gestalt Design and in practice is how most
 software other than the very biggest projects is built.

  I've noticed in my tutorial that several small programs introduce
  various
  classes as the chapter proceeds, then at the end, it is all used to
  make
  the final program. That's fine for the book: no telling how long, or
  what he
  had to do to get it to work that way.

 One of the problems of tutorials (my own included) is that you
 tend to 

Re: [Tutor] designing POOP

2008-02-09 Thread Kent Johnson
bhaaluu wrote:

 When you're designing a program, how do you go about dealing
 with text descriptions, like the descriptions for a room? Here is an
 example of a room description:
 
 THIS IS THE AUDIENCE CHAMBER
 THERE IS A WINDOW TO THE WEST. BY LOOKING TO THE RIGHT
 THROUGH IT YOU CAN SEE THE ENTRANCE TO THE CASTLE.
 DOORS LEAVE THIS ROOM TO THE NORTH, EAST AND SOUTH.

That would probably be an attribute of the Room class.

 The player reads the description, and presses W. There is no west door.
 The program's output is:
 
 YOU CANNOT MOVE THROUGH SOLID STONE
 
 and back to the main prompt. Pressing S moves the player through
 the South door into another room, where the status of the player is
 displayed, and the description of the new room.

It might make sense for Room to have a move(direction) method that 
returns the resulting Room. Then room.move('W') would print the above 
message and return self. room.move('S') would return the room to the south.

This requires that the rooms be linked together - each room knows the 
rooms that are adjacent to it.

Another reasonable design is to have some kind of a Map object that 
holds the linkages between all the rooms, and a method move(from, 
direction) that takes both a Room and a direction.

I don't know which of these would work better for your game.

 The data.py file, with the room descriptions is the biggest file in the
 procedural program. I've been told that a data class with a lot of random
 data in it is a CodeSmell. Is a data class that has room descriptions in
 it, with a function for each room, considered a bad design?

A data file is fine.
 
 And, since the setup table and the function that decides which room
 description is closely related, couldn't they also be a part of that data
 class? Is a data class a CodeSmell when all the functions are related?

I'm not sure I follow you. Are you talking about Room as a data class or 
some other class? What functions do you mean? A class with data and 
related functions is not a data class, it is good design.

 Or, should I have a room class that can instantiate 19 room objects
 which simply accesses the room functions from the data.py file as
 it is?

Maybe you could give a short example of what you are doing.

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-09 Thread Alan Gauld
 ..., I'd like to have the finished program
 be identical to the procedural program as far as I/O goes.

You could do it but it would be easier to change it a little 
because the original games prompts etc betray its internal 
structure. You can just get the objects to return their attributes 
and use string formatting to insert those in your prompts. 
But it might be better to have the objercts return the whole string 
including values. Of course you can do that easily with 
a default parameter in a method:

class Explorer(object):
fmtStr = 
My name is %s
and I have wealth of $%s and 
strength of %s

# other code here

def describe(withText=False)
 values = (self.name, self.wealth, self.strenth)
 if not withText:
  return values
 else
  return fmtStr % values

We can then call that as

e = Explorer()

e.describe(withText=True)   # gets the long version

or

print 
You are an explorer whose name is %s, 
You have wealth of %s and strength of %s
 % e.describe()  # uses tuple result

Using this technique you could use exactly the same text as 
in the original or create a more OO variant where the objects 
all know how to describe themselves. 

Alan G.


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-09 Thread Alan Gauld
bhaaluu [EMAIL PROTECTED] wrote

 When you're designing a program, how do you go about dealing
 with text descriptions, like the descriptions for a room? Here is an
 example of a room description:

 THIS IS THE AUDIENCE CHAMBER
 THERE IS A WINDOW TO THE WEST. BY LOOKING TO THE RIGHT
 THROUGH IT YOU CAN SEE THE ENTRANCE TO THE CASTLE.
 DOORS LEAVE THIS ROOM TO THE NORTH, EAST AND SOUTH.

You can use a class attribute as per my other email example.
This attribute would contain %s markers to substitute the values
as needed. And finally the actual text can be loaded from
a data file by the init method.

 The player reads the description, and presses W. There is no west 
 door.
 The program's output is:

 YOU CANNOT MOVE THROUGH SOLID STONE

 and back to the main prompt. Pressing S moves the player through
 the South door into another room, where the status of the player is
 displayed, and the description of the new room.

OK, See my other porst but you could use the castle as a
coordinator that determines which rooms are available from
any other room. You can build that knowledge into the
rooms - eg by passing the relationships in to the constructor
but that gets hard to maintain, especially in 3D. So I prefer
to have a coordinating object(the castle - or Kent suggested
a Map)

 The data.py file, with the room descriptions is the biggest file in 
 the
 procedural program. I've been told that a data class with a lot of 
 random
 data in it is a CodeSmell. Is a data class that has room 
 descriptions in
 it, with a function for each room, considered a bad design?

The data isn't the problem its the functions and data being mixed
in a class. Having a data file that classes use to set up common
data(class attribnutes) is perfectly valid.

 And, since the setup table and the function that decides which room
 description is closely related, couldn't they also be a part of that 
 data
 class? Is a data class a CodeSmell when all the functions are 
 related?

No a class with functions and the related data is exactly what you
want. What you want to avoid is a classs that has data for two or
more different object types. Or a class with only data.

 Or, should I have a room class that can instantiate 19 room objects
 which simply accesses the room functions from the data.py file as
 it is?

The room objects don't use the functions in data.py rather
those functions become the methods of the class and the data
gets loaded by those methods into the instances. Remember,
objects do it to themselves. Nothing outside the class should
be changing the internal attributes. But it is OK for the class
to load the data from outside - as in a config file.

This is a good thing because it allows you to change the
displayed messages without changing code. For example
to support multiple languages...

 As a side note: Really, the adventure game isn't too much different
 from the Bank Account program in your tutorial:: there are several
 accounts in the adventure game which are credited and debited
 as the game progresses. Pick up treasure: credit my wealth account.

Exactly so. And the ability to recognise that is a big step forward
in recognising abstraction.

Alan G 


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-09 Thread Kent Johnson
Alan Gauld wrote:

 class Explorer(object):
 fmtStr = 
 My name is %s
 and I have wealth of $%s and 
 strength of %s
 
 # other code here
 
 def describe(withText=False)
  values = (self.name, self.wealth, self.strenth)
  if not withText:
   return values
  else
   return fmtStr % values

Should be self.fmtStr or Explorer.fmtStr

 We can then call that as
 
 e = Explorer()
 
 e.describe(withText=True)   # gets the long version
 
 or
 
 print 
 You are an explorer whose name is %s, 
 You have wealth of %s and strength of %s
  % e.describe()  # uses tuple result

Um, yuck. A function that returns either a string or a tuple depending 
on its parameter? How about

class Explorer:
   ...
   def __str__(self):
 fmtStr = 
My name is %s
and I have wealth of $%s and
strength of %s
 return fmtStr % self.values()

   def values(self):
 return (self.name, self.wealth, self.strenth)

Or get rid of values() entirely and just refer to the attributes 
directly - what if you want to print the values in a different order?

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-09 Thread Alan Gauld
Kent Johnson [EMAIL PROTECTED] wrote

 e = Explorer()
 
 e.describe(withText=True)   # gets the long version

 or

 print 
 You are an explorer whose name is %s,
 You have wealth of %s and strength of %s
  % e.describe()  # uses tuple result

 Um, yuck. A function that returns either a string or a tuple 
 depending
 on its parameter? How about

Hmm, I don't have any problerm with that provided it's the same
basic information thats returned in both formats. Using a flag to
control format is quite common in report generators etc (either
postscript or pdf or plain text etc) I would agree its not good if
the actual data being returned was different. But in this case
it's a caller selectable option so there should never be any
confusion.

 class Explorer:
   ...
   def __str__(self):
 fmtStr = 
 My name is %s
 and I have wealth of $%s and
 strength of %s
 return fmtStr % self.values()

I thought about using the str method but decided against it
since you couldn't easily get the string version for manipulation
later - I thought - but of course you could just use the str()
convertion:

s = str(e)

So yes that would be OK.

   def values(self):
 return (self.name, self.wealth, self.strenth)

 Or get rid of values() entirely and just refer to the attributes

Nope, I don't like that as much since it encourages direct
access. And although I don't object to that occasionally - and
prefer it to writing getter methods - in the case where we are
trying to generate a report I believe the object should support
that directly by returning those values that represent it's
state - which might include some that are dynamically
calculated. - but mostly because the object (or its author)
should decide  what it wants the world to know about.

 directly - what if you want to print the values in a different 
 order?

returning a tuple means you can still access the individual
elements via indexing if you don't like the order given. But
you can (ie should) only access those attributes provided
by the values() call.

Alan G. 


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-09 Thread Kent Johnson
Alan Gauld wrote:

   def values(self):
 return (self.name, self.wealth, self.strenth)

 Or get rid of values() entirely and just refer to the attributes
 
 Nope, I don't like that as much since it encourages direct
 access. 

Maybe we just need to agree to disagree here. I don't see how returning 
a tuple is better encapsulation than direct access to named attributes.

And what if an attribute is added? Do you add another value to the 
tuple, forcing every client to change? Start returning a value object 
with named attributes? :-)

 directly - what if you want to print the values in a different 
 order?
 
 returning a tuple means you can still access the individual
 elements via indexing if you don't like the order given. But
 you can (ie should) only access those attributes provided
 by the values() call.

So to print, say, strength, wealth and name, we can have

values = explr.values()
print values[2], values[1], values[0]

or unpack the tuple and give them names again:

strength, wealth, name = explr.values()
print strength, wealth, name

or just use the perfectly good names they already have:
print explr.strength, explr.wealth, explr.name

and of course unless you take extra steps to prevent it, direct 
attribute access is still available even with the values() method...

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-08 Thread Alan Gauld
bhaaluu [EMAIL PROTECTED] wrote

 PyUnit:
 It really doesn't seem to be an absolute beginner technique.

Unit tests and TDD is not a design technique per se.
It is definitely not a technique for designing OOP programs
its a programming technique that makes code more reliable
(whether OOP or not).

Where it does help in design is by focussing attention
on how a class (or function) should behave from the consumers
perspective. This is always a good thing. But TDD in itself will
not help you identify classes or their interactions. It will help
you build classes that are user friendly and work as expected.

 The noun/verb/adjective technique seems to be geared
 more towards beginners. I like the idea of that technique.

It is completely intended for beginners. It is, in practice, a little
too naive for production type use but it is a good starting point
when you don't know where to go and don;t have lots of
experience in the problem domain. What nouns/verbs does
is identify candidate classes and operations. It says nothing
about how those operations are to be coded or used. Once
you know what classes you want to write TDD can help
you build them better, but you have to identify them first!

 One thing I'm encouraged by: in Alan's tutorial, he
 says that I don't have to see the light to use POOP.

Absolutely, you have been using string objects and file
objects already. You can use classes to bundle data
and methods together and use them in an object based
approach without fully understanding OOP. But OOP
does open up new avenues and possibilities and,
particularly in larger programs, offers significant savings
in effort and reuse.

-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld 


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-08 Thread Kent Johnson
Alan Gauld wrote:

 Unit tests and TDD is not a design technique per se.
 It is definitely not a technique for designing OOP programs
 its a programming technique that makes code more reliable
 (whether OOP or not).
 
 Where it does help in design is by focussing attention
 on how a class (or function) should behave from the consumers
 perspective.

I agree that TDD is not a design technique, but it does strongly 
influence design by introducing testability as a design requirement. TDD 
strongly encourages loose coupling and reusability.
- loose coupling because classes and functions that depend on many other 
classes/functions/modules are harder to test
- reusability because of the loose coupling and because any code that 
has unit tests already has two clients - the production code and the tests.

I like to say, no code is reusable until it has been reused. Although a 
bit of an overstatement, there is a lot of truth in it. It is very hard 
to anticipate how a bit of code might be reused without actual reuse. 
TDD provides an artificial second use which promotes reusability.

TDD also promotes incremental development where the design evolves to 
meet current requirements. This is sometimes called Test-Driven Design:
http://www.agiledata.org/essays/tdd.html
http://www.salientblue.com/blog/?p=10

So TD development can be part of a process that includes design.

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-08 Thread Kent Johnson
bhaaluu wrote:

 class Explorer(object):
 player
 def __init__(self,name):
 initilaization method
 self.__name = name
 self.strength = 20
 self.wealth = 60
 
 def get_name(self):
 return self.__name

There is no need for get_name(). Just refer to explr.name, the same as 
for strength and wealth.

 class Light(object):
 light switch
 
 def __init__(self,light):
 self.light = light
 
 def state(self):
 if self.light == 0:
 print ( IT IS TOO DARK TO SEE ANYTHING)
 else:
 print ( THE LIGHTS ARE ON, BUT NO ONE'S HOME)

show_state() or print_state() might be a better name. If you call this 
method __str__() and just return the string instead of printing it, it 
will be called when you
   print switch

 def cs():
 print \n*50
 
 def main():
 tally = 0
 switch = Light(0) #instance
 cs() # clear screen
 name = raw_input( WHAT IS YOUR NAME, EXPLORER? )
 explr = Explorer(name)
 while True:
 cs() # clear screen
 print ( %s, YOUR STRENGTH IS %d % (explr.get_name(), 
 explr.strength))
 print ( YOU HAVE $%d % explr.wealth)

This could be Explorer.__str__():
   def __str__(self):
 return  %s, YOUR STRENGTH IS %d\n YOU HAVE $%d % 
(self.get_name(), self.strength, self.wealth)

Then the prints become just
   print explr

 switch.state()
 print
 print
 answer = raw_input( WHAT DO YOU WANT TO DO? [Q|L]: )
 if answer.upper() == Q:
 break
 if answer.upper() == L:
 if switch.light == 1:
 switch.light = 0
 else:
 switch.light = 1
 explr.strength -= 5
 explr.wealth -= 15
 if explr.wealth = 0:
 print
 print ( YOU HAVE NO MONEY)
 time.sleep(1)
 if explr.strength = 0:
 print
 print ( YOU DIED...)
 time.sleep(1)
 break

This could be two Explorer methods:
   def change_wealth(self, incr):
 self.wealth += incr
 if self.wealth = 0:
   print
   print ( YOU HAVE NO MONEY)
   time.sleep(1)

Then call
   explr.change_wealth(-15)

Strength is a little trickier because you need to break out of the loop. 
You could have
   def change_strength(self, incr):
 self.strength += incr
 if self.strength = 0:
   print
   print ( YOU DIED...)
   time.sleep(1)
   self.alive = False

Then in Explorer.__init__() set
   self.alive = True

and change the loop from
   while True:
to
   while explr.alive:

This would give you an Explorer class that actually does something useful.

Kent

 else:
 print ( INVALID CHOICE)
 tally += 1
 print
 print ( FINAL SCORE:)
 print (TALLY: %d % tally)
 print ( STRENGTH: %d % explr.strength)
 print (   WEALTH: $%d % explr.wealth)
 
 if __name__ == __main__:
 main()
 
 Happy Programming!

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-08 Thread bhaaluu
On Feb 8, 2008 3:24 PM, Kent Johnson [EMAIL PROTECTED] wrote:
 
 and change the loop from
while True:
 to
while explr.alive:

 This would give you an Explorer class that actually does something useful.

 Kent


It also cleaned up main(), and put everything in well defined packages
at the top of the program. I can see do difference in game play. 8^D
Here are your changes implemented, and working on my Linux system:

#!/user/bin/python

import time

class Explorer(object):
player
def __init__(self,name):
initilaization method
self.name = name
self.strength = 20
self.wealth = 60
self.alive = True

def __str__(self):
return  %s, YOUR STRENGTH IS %d\n YOU HAVE $%d % (self.name,
self.strength, self.wealth)

def change_wealth(self, incr):
self.wealth += incr
if self.wealth = 0:
print
print ( YOU HAVE NO MONEY)
time.sleep(1)

def change_strength(self, incr):
self.strength += incr
if self.strength = 0:
print (\n\n YOU DIED...)
time.sleep(1)
self.alive = False

class Light(object):
light switch

def __init__(self,light):
self.light = light

def __str__(self):
if self.light == 0:
return  IT IS TOO DARK TO SEE ANYTHING
else:
return  THE LIGHTS ARE ON, BUT NO ONE'S HOME

def cs():
print \n*50

def main():
tally = 0
switch = Light(0) #instance
cs() # clear screen
name = raw_input( WHAT IS YOUR NAME, EXPLORER? )
explr = Explorer(name)
while explr.alive:
cs() # clear screen
print explr
print switch
print
print
answer = raw_input( WHAT DO YOU WANT TO DO? [Q|L]: )
if answer.upper() == Q:
break
if answer.upper() == L:
if switch.light == 1:
switch.light = 0
else:
switch.light = 1
explr.change_wealth(-15)
explr.change_strength(-5)
else:
print ( INVALID CHOICE)
tally += 1
print
print ( FINAL SCORE:)
print (TALLY: %d % tally)
print ( STRENGTH: %d % explr.strength)
print (   WEALTH: $%d % explr.wealth)

if __name__ == __main__:
main()

Thanks Kent!
I like these small incremental changes with explanations.
I especially like the way you took blocks of code from main()
and made methods out of them. The actual code itself,
hardly changed!

Happy Programming!
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-08 Thread bhaaluu
On Feb 7, 2008 9:40 PM, Tiger12506 [EMAIL PROTECTED] wrote:
 There's a couple of errors in here that no one has addressed yet because the
 question was geared towards programming style... So now I will address them.
 Or undress them, I suppose. ;-)

I didn't make much progress until I started thinking
about the Explorer and Light classes as actual objects.

I've tried to address what you undressed. 8^D
Here is another version to undress:

#!/user/bin/python

import time

class Explorer(object):
player
def __init__(self,name):
initilaization method
self.__name = name
self.strength = 20
self.wealth = 60

def get_name(self):
return self.__name

class Light(object):
light switch

def __init__(self,light):
self.light = light

def state(self):
if self.light == 0:
print ( IT IS TOO DARK TO SEE ANYTHING)
else:
print ( THE LIGHTS ARE ON, BUT NO ONE'S HOME)

def cs():
print \n*50

def main():
tally = 0
switch = Light(0) #instance
cs() # clear screen
name = raw_input( WHAT IS YOUR NAME, EXPLORER? )
explr = Explorer(name)
while True:
cs() # clear screen
print ( %s, YOUR STRENGTH IS %d % (explr.get_name(), explr.strength))
print ( YOU HAVE $%d % explr.wealth)
switch.state()
print
print
answer = raw_input( WHAT DO YOU WANT TO DO? [Q|L]: )
if answer.upper() == Q:
break
if answer.upper() == L:
if switch.light == 1:
switch.light = 0
else:
switch.light = 1
explr.strength -= 5
explr.wealth -= 15
if explr.wealth = 0:
print
print ( YOU HAVE NO MONEY)
time.sleep(1)
if explr.strength = 0:
print
print ( YOU DIED...)
time.sleep(1)
break
else:
print ( INVALID CHOICE)
tally += 1
print
print ( FINAL SCORE:)
print (TALLY: %d % tally)
print ( STRENGTH: %d % explr.strength)
print (   WEALTH: $%d % explr.wealth)

if __name__ == __main__:
main()

Happy Programming!
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-08 Thread bhaaluu
On Feb 8, 2008 4:46 PM, Kent Johnson [EMAIL PROTECTED] wrote:
 bhaaluu wrote:

  It also cleaned up main(), and put everything in well defined packages
  at the top of the program.

 Yes, good OOD puts things into cohesive, comprehensible packages.

  I can see do difference in game play. 8^D

 And that's a good thing, right?

 Refactoring is the process of changing a software system in such a way
 that it does not alter the external behavior of the code yet improves
 its internal structure. -- Martin Fowler in Refactoring

 The refactoring you just did is called Extract Method:
 http://www.refactoring.com/catalog/extractMethod.html

 Kent


This is something that one can only gain from experience?
I really had to struggle to get the Light class to work at all.
I have no idea how many times I started over. But I do feel
that I am starting to learn some of this stuff.

As simple as the adventure game is, I can see that it will
provide lots of practice for me to design and code it in
Python OOP.

Thanks Kent!
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-08 Thread Kent Johnson
bhaaluu wrote:
 On Feb 8, 2008 4:46 PM, Kent Johnson [EMAIL PROTECTED] wrote:
 Refactoring is the process of changing a software system in such a way
 that it does not alter the external behavior of the code yet improves
 its internal structure. -- Martin Fowler in Refactoring

 This is something that one can only gain from experience?

Experience and study. I don't think there is much substitute for 
experience to see *why* OOP and refactoring and clean design are useful. 
There is nothing like growing a program to the point where you don't 
know how it works or how to change it to make you appreciate good design 
:-) Studying gives you good examples to follow and new techniques to try.

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-08 Thread Kent Johnson
bhaaluu wrote:

 It also cleaned up main(), and put everything in well defined packages
 at the top of the program.

Yes, good OOD puts things into cohesive, comprehensible packages.

 I can see do difference in game play. 8^D

And that's a good thing, right?

Refactoring is the process of changing a software system in such a way 
that it does not alter the external behavior of the code yet improves 
its internal structure. -- Martin Fowler in Refactoring

The refactoring you just did is called Extract Method:
http://www.refactoring.com/catalog/extractMethod.html

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-08 Thread Tiger12506
 This is something that one can only gain from experience?
 I really had to struggle to get the Light class to work at all.
 I have no idea how many times I started over. But I do feel
 that I am starting to learn some of this stuff.

This surprises me... I guess it does take experience. What is the most basic 
thing you can describe about a light? Immediately I answer, You can turn it 
on or off. This suggests methods, turn_on(), turn_off(), and something to 
maintain the state of the light attribute - i.e. whether it is currently on 
or not. I suggest practice practice practice. You should be able to look at 
anything in your house and be able to design a basic class for it. Some that 
come to mind as I look around the room. I've often thought of redesigning my 
entire house in OOP. ;-)

(Granted - these examples aren't entirely useful, but they provide examples 
of practice with methods and attributes.)

class Pen:
  def __init__(self):
self.level = 50
self.on = False
  def click(self):
self.on = (not self.on)
  def isempty(self):
return (self.level  0)
  def write(self):
if self.isempty:
  return False
if not self.on:
  return False
self.level = self.level - 5
return True

class Knob:
  def __init__(self, locked=False):
self.locked = locked
  def turn(self):
if self.locked:
  return False
return True

class Door:
  def __init__(self):
self.knob = Knob()
  def lock(self):
self.knob.locked = True
  def unlock(self):
self.knob.locked = False
  def open(self):
return self.knob.turn()

Are some simple examples off the top of my head. It's not difficult to model 
real-life things with classes, but it is much more difficult to model them 
in such a way that you interact with them normally. (i.e. do you lock the 
door, or the knob? Does the knob contain a Lock, or does the developer only 
need to know that it has one and whether it is locked or not?) 

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-08 Thread Alan Gauld
bhaaluu [EMAIL PROTECTED] wrote

There have been lots of comments about this already but
I'm deliberately jumping in at this level because I want
to pick up a few general points...

 class Explorer(object):
player
def __init__(self,name):
initilaization method
self.__name = name
self.strength = 20
self.wealth = 60

def get_name(self):
return self.__name

Kent already pointed out this is not needed.

But as a general rule consider what I said earlier about
objects being based on behaviour. And that the data should
be there to support the behaviour.
So in this case ask:
Why do I have a name, strength and wealth?
What behaviour do these support?

Behaviour is expressed as methods so I am expecting to
see methods sof Explorer that use the attributes, otherwise
the Explorer is just a data container like a list or dictionary.

 class Light(object):
light switch

def __init__(self,light):
self.light = light

def state(self):
if self.light == 0:
print ( IT IS TOO DARK TO SEE ANYTHING)
else:
print ( THE LIGHTS ARE ON, BUT NO ONE'S HOME)

You have a method here that reports the state but
doesn't a light switch usually do something?
Like turn the light on or off?
Usually by a toggle operation?
So maybe a toggle method would be good:

 def toggle(self):
 self.light == not self.light   # make it a boolean

Also remembering the principle that UI and logic should be
separated it might be good to pull the printing out of the
class and just let the method returmn the string. And as
Kent already suggested for Explorer that could be done
with an __str__ method so all you need do in the consumer
is:

print switch

 def cs():
print \n*50

 def main():
tally = 0
switch = Light(0) #instance
cs() # clear screen
name = raw_input( WHAT IS YOUR NAME, EXPLORER? )
explr = Explorer(name)
while True:
cs() # clear screen
print ( %s, YOUR STRENGTH IS %d % (explr.get_name(), 
 explr.strength))
print ( YOU HAVE $%d % explr.wealth)

Kent has addressed this specifically but as a general rule remember
the consumer should not have to get at the data attributes of an 
object.
You should only need to send messages to the Explorer, in this case
it's a status report - which we already said can be done via a __str__
method.

switch.state()
print
print
answer = raw_input( WHAT DO YOU WANT TO DO? [Q|L]: )
if answer.upper() == Q:
break
if answer.upper() == L:
if switch.light == 1:
switch.light = 0
else:
switch.light = 1

And here is the toggle method, except its in your program
rather than in the object. Let the object do it to itself, do not
try to mess with the data directly

   if answer.upper() == L:
 switch.toggle()

explr.strength -= 5
explr.wealth -= 15


Now I'm not quite sure why you decrease these but again
the Explorer should be doing it to himself - objects do it
to themselves. If the Explorer always loses strengty and
wealth after a turn then the method could be called
newTurn() or somesuch. But I suspect there might be
a more meaningful name we could use.


if explr.wealth = 0:
print
print ( YOU HAVE NO MONEY)
time.sleep(1)
if explr.strength = 0:
print
print ( YOU DIED...)
time.sleep(1)
break

And all of this could be built into the explorer method above,
maybe implemented as an exception?

def newTiurn(self):
 self.wealth -= 15
 self.strength -= 5
 if self.wealth = 0:
 raise ExplorerBroke
 if self.strength = 0
 raise ExplorerDied

You control code then looks something like:

   if answer.upper() == L:
 switch.toggle()
 try: explr.newTurn()
 except ExplorerBroke e: print e.message
 except ExplorerDied e: print e.message

Or with a bit more intelligence in the __str__ method

   if answer.upper() == L:
 switch.toggle()
 try: explr.newTurn()
 except ExplorerBroke,ExplorerDied:
 print explr

Really the outside control code should be focused around
the user interaction and senmding messages to the objects.
It should not be pulling out data from inside the objects to
do anything with it, that is the job of the objects.

Occasionally we can break that rule if its just for printing
or maybe to assign directly to another value. For example
you could directly access switch.light if you needed to
pass that into a method of explorer


Re: [Tutor] designing POOP

2008-02-08 Thread Tiger12506
 There is nothing like growing a program to the point where you don't
 know how it works or how to change it to make you appreciate good design

Amen. I was recently fighting with an example of a multi-client, simple 
server that I wanted to translate into assembly. Not only was the code 
unreadable, but they had tried to apply a functional programming technique 
that failed miserably.

Final result: Less # of lines, better readability, and slightly more 
algorithm efficient. Even with that change of language to something 
horrendously verbose.

Key idea:  Choose a design wisely. Understand that if a design does not 
enhance readability or code reusability, it's a bad design. 

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread Alan Gauld
Kent Johnson [EMAIL PROTECTED] wrote

 Let me say that I don't mean any disrespect for Alan or his 
 approach, I
 just have a different point of view.

Heh, heh! I was waiting for someone to post a message like this.
I'll respond by saying the noun/verb thing is not actually the
method I would normally use (although when all else fails I
do drop back to it as a starter technique). However I have found
it to be a techhnique that woerks well for beginners who don't
know how to get started. Partly because it is fairly mechanistic.

But noun/verb does have some problems and often produces
designs that have too many classes and that do not make
best use of OOP idioms like polymorphism or abstraction.
But for beginners and in small problems it is a good starter.

 Also I will say that converting a procedural program to OO 'just
 because' is not necessarily a good idea. Not every program is 
 improved
 by OOP. In your case, it probably will be though.

This is absolutely true. Too many people approach OOP as
if it were some kind of holy grail that is inherently better
than other styles - it isn't, its just another tool in the toolkit.

 I tend to work from small pieces to larger ones and let the design 
 grow
 from the needs of the code, rather than from considerations of nouns 
 and
 verbs in the spec.

I agree at the micro level and in fact my discussion of
explorers and monsters merging into a figher superclass
hopefully illustrates how that micro level design/code cycle
can generate new features of a design including new
classes/objects. Many OO Design gurus have commented
on the way that OO design tends to cycle between top down
design - identifying core classes - and bottom up design - writing
the lowest building blocks and using that to discover more
about the higher level needs.

OO design is a very organic process compared to procedural
design which tends to bemuch more top down and heirarchical
in nature. In my experience at least.

 accommodate it. Design a little, code a little, repeat...
 http://personalpages.tds.net/~kent37/stories/3.html

Exactly so.

 The writings of Robert C Martin have taught me a lot about good 
 design
 and agile development. They don't all apply to Python

Martin is very good on Agile, I'm less impressed with his OO writing,
largely because he does tend to see the world through the eyes
of C++ and Java, both of which have a very singular view of OO
which does not always work in other more dynamic OOP
languages (Lisp, Smalltalk, Python, JavaScript etc)

 I don't use the command-line interpreter much, I do a lot more work 
 in
 unit tests. In test-driven development (TDD), if you decide you want 
 a
 Room class, the first thing you do is create a unit test for the 
 class.

For production programming I wholly endorse that approach,
for exploring and inventing code structures (which is mainly
what I use Python for, the results get converted to Java
where we use TDD) I find the interpreter is very useful.

To use TDD effectively you first need to know what you are
trying to do. An example of bad use of TDD can be found in
one of Robert Martins books where he tries to give an example
of pair programming of a bowling game scorer. Unfortunately
because of the haphazard design approach they wind up
with code that is both bloated (it repeats an algorithm twice)
and faulty (one of the algorithm implementations is broken).
Unfortunately they don't detect the fault because the test data
they used missed out all of the cases where the defect is
exhibited... Note it wasn't the test that was broken it was
the limited data set used. And that is one of the big limitations
of TDD, it is only as effective as the test data.

It is important to realize that there is no single way to design
OOP programs. The noun/verb thing is a good way to get
started and often effective when nothing else seems to
be working. But there are plenty of other approaches out
there and books by authors like Booch, Rumbaugh, Jacobsen,
Schaer/Mellor, Coad/Yourdon, Wirfs-Brock and yes, Robert Martin
are all worh reading to see the different approaches available.
The Coad/Nicola OOP book is especially interesting because
it contrasts the same problems in C++ and Smalltalk (which
is conceptually close to python) and shows how the choice
of language can have a big impact on detailed OOP design
decisions.

Once you get experienced in OPP you will not
use the noun/verb te4chnique very often because your brain
will start to think in terms of objects without need of intermediate
tools. In fact when I went back to COBOL for the Y2K bug I
found it hard initially to think procedurally because I'd been
using OOP for so long by then. Nowadays I don;t write so
much code I find I switch between both modes of design
without really thinking too much about it. On small scale
stuff I tend to go procedural but on big problems I tend to
go OOP.

Alan G. 


___
Tutor maillist  -  

Re: [Tutor] designing POOP

2008-02-07 Thread bhaaluu
On Feb 6, 2008 8:15 PM, Kent Johnson [EMAIL PROTECTED] wrote:
 
 Design a little, code a little, repeat...
 http://personalpages.tds.net/~kent37/stories/3.html

 
 You can discover many useful design techniques by applying DRY. More here:
 http://personalpages.tds.net/~kent37/stories/00012.html

 
 It has a chapter that explains the code smells and points out
 ways to fix them. An abbreviated version is available here:
 http://wiki.java.net/bin/view/People/SmellsToRefactorings

 The writings of Robert C Martin have taught me a lot about good design
 and agile development.  A lot of his work is available on-line:
 http://objectmentor.com/resources/publishedArticles.html

 http://objectmentor.com/resources/articles/Principles_and_Patterns.pdf
 might be a good starting point.
 http://objectmentor.com/resources/articles/xpepisode.htm attempts to
 give the flavor of agile, test-driven development.

 I don't use the command-line interpreter much, I do a lot more work in
 unit tests.  I have written a little more about this here:
 http://personalpages.tds.net/~kent37/stories/7.html

 HTH,
 Kent

Thank you Kent! I am open to all suggestions as to where to get started
learning how to  design with the Python Object-Oriented Paradigm.
I'm doing a lot of reading, some coding (in my 'testing' directory),
and a lot of thinking about what I'm trying to do. This is a learning situation.
Since I'm a Hobbyist programmer, I don't have a 'class' deadline to meet
(and believe me, I'm happy about that!). I do feel that learning how to do this
will enhance the enjoyment of my Hobby for years to come. I do know that
it will open a lot of doors for me that are currently closed, especially when
it comes to creating games with Python/PyGame, and so forth. Plus, it is
quite possible that this discussion will benefit others who are also just
beginning.

Happy Happy Joy Joy.
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread Kent Johnson
Alan Gauld wrote:
 Kent Johnson [EMAIL PROTECTED] wrote
 The writings of Robert C Martin have taught me a lot about good 
 design
 and agile development. They don't all apply to Python
 
 Martin is very good on Agile, I'm less impressed with his OO writing,
 largely because he does tend to see the world through the eyes
 of C++ and Java, both of which have a very singular view of OO
 which does not always work in other more dynamic OOP
 languages (Lisp, Smalltalk, Python, JavaScript etc)

I found his writing on principles of OO design very helpful when I was a 
C++ programmer. I admit I have not revisited them from the point-of-view 
of a Python programmer. I'm sure some of the techniques are not needed - 
the pervasive use of interfaces, in particular - but the underlying 
principles should still apply.

Taking a closer look, I think these still have something to offer:
The Liskov Substitution Principle
http://objectmentor.com/resources/articles/lsp.pdf

Inheritance vs. Delegation (Template Method and Strategy patterns)
http://objectmentor.com/resources/articles/inheritanceVsDelegation.pdf

The Craftsman series might be of interest.

One thing to keep in mind is that when C++ and Java use interfaces, 
Python uses duck typing. C++ and Java use classes to encapsulate 
functions (e.g. in Strategy) but Python can use functions directly.

Kent

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread Marc Tompkins
 Sorry, my bad - this was my me, but I forgot to hit Reply All.
My me?  I think I meant to type my message.
-- 
www.fsrtechnologies.com
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread Kent Johnson
bhaaluu wrote:
 Best practice?

Use class attributes when you actually want a shared attribute, for 
example for constants with class scope, or as defaults when instance 
attributes may not be assigned. Class attributes can be redefined by 
subclasses which makes them useful as a way to configure a class.

Don't use them strictly as documentation. Write a docstring instead.

My $.02
Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread bob gailer
Also beware the difference between reassigning and extending:

class F:
  a = 3
  b = []
  def __init__(self, a, b):
self.a = a
self.b.append(b)
  def show(self):
print self.a, self.b

f1=F(1,2)
f2=F(3,4)
f1.show() # 1 [2, 4]
f2.show() # 3 [2, 4]

-- 
Bob Gailer
919-636-4239 Chapel Hill, NC

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread bhaaluu
I was asked:

quote

Here's a situation I often encounter, and I was wondering what the
best practice is.  I've generally initialized my classes' attributes
this same way:

 class TestClass1(object):
  please give me a better name
 def __init__(self):
 please document me
 self.name = 
 self.answer = 
 self.strength = 20
 self.wealth = 45
 self.light = 0
 self.tally = 0

but it could also be done like so:

 class TestClass1(object):
  please give me a better name
 name = 
 answer = 
 strength = 20
 wealth = 45
 light = 0
 tally = 0
 def __init__(self,name=Zed):
 please document me
 self.name = name
 ...etc.

I realize that the two are NOT equivalent if you're using the class as
a static class, rather than instantiating it (e.g. using a static
class called Global while weaning oneself from global variables...)
However, I'm asking about this present case: the class under
discussion will always be instantiated.  It seems to me that declaring
the attributes in the class body makes the class more amenable to
introspection, but are there downsides I'm not seeing?  What's the
best practice?

/quote

I've tried both ways and can't see any difference between
the two as far as input/output is concerned.

Best practice?
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread Kent Johnson
bhaaluu wrote:

 The TDD method is the method used in my tutorial:
 Python Programming for the Absolute Beginner 2E. Michael Dawson. 2006.
 Dawson uses a very simple Tamagotchi example called Critter Caretaker
 to introduce the mechanics of POOP. However, perhaps he is using
 the TDD method of design?

I don't think Dawson uses TDD. AFAIK he doesn't talk about unit-testing 
at all, which is the fundamental practice of TDD. For an example of unit 
tests in Python, see
http://docs.python.org/lib/minimal-example.html

 here is
 a first little testing snippet from the testing directory, using the TDD
 method. I'm confident that if I am using the terminology incorrectly,
 someone will point out the error of my ways. 

I think you are using the terminology incorrectly. I would call this an 
example of experimental programming, maybe. A classic example of TDD in 
Java is here:
http://junit.sourceforge.net/doc/testinfected/testing.htm

 class TestClass1(object):
  please give me a better name
 def __init__(self):
 please document me
 self.name = 
 self.answer = 
 self.strength = 20
 self.wealth = 45
 self.light = 0
 self.tally = 0

This is a good example of a data class - a class that is just a 
container for data. That is a code smell. It seems to contain unrelated 
values - name and strength are attributes of the player, light is an 
attribute of the environment. So it should probably be more than one 
class, or, since the entire program is in one loop, these could just be 
local variables of main().

 def main():
 tc1 = TestClass1() # instance
 tc1.__init__() # invoke method

The __init__() method is called implicitly by calling TestClass1(). 
Generally the only time you explicitly call __init__() is when calling 
the method of a base class.

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread bhaaluu
On Feb 7, 2008 4:58 PM, Eric Brunson [EMAIL PROTECTED] wrote:
 bhaaluu wrote:
  What is the equivalent of JUnit in Python? The article says that JUnit is
  used for unit tests, or you can write your own. Since I don't have a clue,
  writing my own is probably out the question. Also I'm not familiar with
  Java, and am just learning Python OOP, so I'm not getting much out
  of that one. Sorry. Absolute Beginner here.
 

 http://www.google.com/search?q=python+unit+test

 Cleverly called unittest, though sometimes referred to by its original
 project name PyUnit.

 :-)


Cool!
http://docs.python.org/lib/module-unittest.html

The Python unit testing framework, sometimes referred to as ``PyUnit,'' is
a Python language version of JUnit, by Kent Beck and Erich Gamma. JUnit is,
in turn, a Java version of Kent's Smalltalk testing framework. Each is the de
facto standard unit testing framework for its respective language.

Who would have thunk it?
I'll Google and see if I can find a nice PyUnit tutorial.

So, is my first try dong a unit test a total bit-bucket case?
No way to make a test case out of it?
That would be a good example (for me). 8^D
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread bhaaluu
Greetings,

I've read both Kent's and Alan's approaches to designing a POOP,
and am intrigued with the possibilities of the noun/verb/adjective
technique, but am also sympathetic to the TDD method as well
because it is how I've always programmed. I have noted Alan's
comments on the limitations of TDD, as well as the limitations
of the noun/verb/adjective method of design.

The TDD method is the method used in my tutorial:
Python Programming for the Absolute Beginner 2E. Michael Dawson. 2006.
Dawson uses a very simple Tamagotchi example called Critter Caretaker
to introduce the mechanics of POOP. However, perhaps he is using
the TDD method of design?

I'm still experimenting with the noun/verb/adjective design technique,
but I was also itching to get started on something as well, so here is
a first little testing snippet from the testing directory, using the TDD
method. I'm confident that if I am using the terminology incorrectly,
someone will point out the error of my ways. The Tutors are always
saying they really can't help unless they see some code, so this is
a simple adventure game that involves switching a light on and off.
The gameplay isn't all that great, but it is a start. 8^D

#!/user/bin/python

From the testing laboratory of:
b h a a l u u at g m a i l dot c o m
2008-02-07


import time

CS = \n*50

class TestClass1(object):
 please give me a better name
def __init__(self):
please document me
self.name = 
self.answer = 
self.strength = 20
self.wealth = 45
self.light = 0
self.tally = 0

def main():
tc1 = TestClass1() # instance
tc1.__init__() # invoke method
print CS
N1 = tc1.name
N1 = raw_input( WHAT IS YOUR NAME, EXPLORER? )
# main game loop
while True:
print CS
print ( %s, YOUR STRENGTH IS %d) % (N1, tc1.strength)
print ( YOU HAVE $%d) % tc1.wealth
if tc1.light == 0:
print ( IT IS TOO DARK TO SEE ANYTHING)
else:
print ( THE LIGHT'S ON, BUT NO ONE'S HOME)
print
print
A = tc1.answer
A = raw_input( WHAT DO YOU WANT TO DO? [Q|L]: ) # main game prompt
if A.upper() == Q:
break
if A.upper() == L:
light = raw_input( LIGHT? [0|1]: ) # turn the light on and off
if light == 0 and tc1.light == 0:
print ( THE LIGHT IS OFF)
time.sleep(2)
if tc1.wealth = 0:
print
print ( YOU HAVE NO MONEY)
time.sleep(2)
else:
tc1.light = int(light)
tc1.wealth -= 15
else:
print ( INVALID CHOICE)
time.sleep(2)
tc1.tally += 1
tc1.strength -= 5
if tc1.strength = 0:
print ( YOU DIED)
time.sleep(2)
break
print
print ( Final Score:)
print (Tally: %d) % tc1.tally
print (   Wealth: $%d) % tc1.wealth
print ( Strength: %d) % tc1.strength

if __name__ == __main__:
main()


On Feb 7, 2008 4:15 AM, Alan Gauld [EMAIL PROTECTED] wrote:
 Kent Johnson [EMAIL PROTECTED] wrote

  Let me say that I don't mean any disrespect for Alan or his
  approach, I
  just have a different point of view.

 Heh, heh! I was waiting for someone to post a message like this.
 I'll respond by saying the noun/verb thing is not actually the
 method I would normally use (although when all else fails I
 do drop back to it as a starter technique). However I have found
 it to be a techhnique that woerks well for beginners who don't
 know how to get started. Partly because it is fairly mechanistic.

 But noun/verb does have some problems and often produces
 designs that have too many classes and that do not make
 best use of OOP idioms like polymorphism or abstraction.
 But for beginners and in small problems it is a good starter.

  Also I will say that converting a procedural program to OO 'just
  because' is not necessarily a good idea. Not every program is
  improved
  by OOP. In your case, it probably will be though.

 This is absolutely true. Too many people approach OOP as
 if it were some kind of holy grail that is inherently better
 than other styles - it isn't, its just another tool in the toolkit.

  I tend to work from small pieces to larger ones and let the design
  grow
  from the needs of the code, rather than from considerations of nouns
  and
  verbs in the spec.

 I agree at the micro level and in fact my discussion of
 explorers and monsters merging into a figher superclass
 hopefully illustrates how that micro level design/code cycle
 can generate new features of a design including new
 classes/objects. Many OO Design gurus have commented
 on the way that OO design tends to cycle between top down
 design - identifying core classes - and bottom up design - writing
 the lowest building blocks and using that to discover more
 about the higher level needs.

 OO 

Re: [Tutor] designing POOP

2008-02-07 Thread bhaaluu
On Feb 7, 2008 4:07 PM, Kent Johnson [EMAIL PROTECTED] wrote:
 bhaaluu wrote:

  The TDD method is the method used in my tutorial:
  Python Programming for the Absolute Beginner 2E. Michael Dawson. 2006.
  Dawson uses a very simple Tamagotchi example called Critter Caretaker
  to introduce the mechanics of POOP. However, perhaps he is using
  the TDD method of design?

 I don't think Dawson uses TDD. AFAIK he doesn't talk about unit-testing
 at all, which is the fundamental practice of TDD. For an example of unit
 tests in Python, see
 http://docs.python.org/lib/minimal-example.html

  here is
  a first little testing snippet from the testing directory, using the TDD
  method. I'm confident that if I am using the terminology incorrectly,
  someone will point out the error of my ways.

 I think you are using the terminology incorrectly. I would call this an
 example of experimental programming, maybe. A classic example of TDD in
 Java is here:
 http://junit.sourceforge.net/doc/testinfected/testing.htm

What is the equivalent of JUnit in Python? The article says that JUnit is
used for unit tests, or you can write your own. Since I don't have a clue,
writing my own is probably out the question. Also I'm not familiar with
Java, and am just learning Python OOP, so I'm not getting much out
of that one. Sorry. Absolute Beginner here.


  class TestClass1(object):
   please give me a better name
  def __init__(self):
  please document me
  self.name = 
  self.answer = 
  self.strength = 20
  self.wealth = 45
  self.light = 0
  self.tally = 0

 This is a good example of a data class - a class that is just a
 container for data. That is a code smell. It seems to contain unrelated
 values - name and strength are attributes of the player, light is an
 attribute of the environment. So it should probably be more than one
 class, or, since the entire program is in one loop, these could just be
 local variables of main().

Well, most of these were local variables in main() in the procedural
version of this program. So DataClass() is what I should name such
a class. I was wondering about that. These variables were all initialized
in the procedural program before the loop started. Also, the Castle
was setup as part of the initialization, but I'm not dealing with that
here. I'm just trying to learn how to design here. I figured I'd put the
Castle setup in it's own class because it is an object (using the
model as a real-world object method). I don't think I can worry
about whether the CodeSmells at this point. I'm thinking I need
to design something that works, then be able to refactor it to
eliminate as many CodeSmells as I can. But! Noted: a DataClass
is a CodeSmell.


  def main():
  tc1 = TestClass1() # instance
  tc1.__init__() # invoke method

 The __init__() method is called implicitly by calling TestClass1().
 Generally the only time you explicitly call __init__() is when calling
 the method of a base class.

I can fix that right now! Back to the laboratory! 8^D


 Kent


Happy Programming!
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread Eric Brunson
bhaaluu wrote:
 What is the equivalent of JUnit in Python? The article says that JUnit is
 used for unit tests, or you can write your own. Since I don't have a clue,
 writing my own is probably out the question. Also I'm not familiar with
 Java, and am just learning Python OOP, so I'm not getting much out
 of that one. Sorry. Absolute Beginner here.
   

http://www.google.com/search?q=python+unit+test

Cleverly called unittest, though sometimes referred to by its original 
project name PyUnit.

:-)
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread Kent Johnson
bhaaluu wrote:
 What is the equivalent of JUnit in Python? 

The unittest module is based on JUnit.
http://docs.python.org/lib/module-unittest.html

Here is a simple introduction to the capabilities of unittest. It 
doesn't do much to motivate the examples though:
http://www.oreillynet.com/onlamp/blog/2007/09/pymotw_unittest.html

A longer intro:
http://agiletesting.blogspot.com/2005/01/python-unit-testing-part-1-unittest.html

An alternative to unittest is doctest. They both get the job done, which 
one to use is mostly a matter of preference and the complexity of the tests.
http://docs.python.org/lib/module-doctest.html

Wikipedia has a short introduction to doctest and a link to Tim Peter's 
c.l.py posting introducing the module:
http://en.wikipedia.org/wiki/Doctest
http://groups.google.com/group/comp.lang.python/msg/1c57cfb7b3772763

Another intro:
http://agiletesting.blogspot.com/2005/01/python-unit-testing-part-2-doctest.html

There are many other testing tools that are not in the standard library. 
Nose and py.test are popular alternatives to unittest and doctest.
http://agiletesting.blogspot.com/2005/01/python-unit-testing-part-3-pytest-tool.html

Here is a good list of testing articles:
http://www.pycheesecake.org/wiki/AgileTestingArticlesAndTutorials

Here is a pretty comprehensive list of tools:
http://pycheesecake.org/wiki/PythonTestingToolsTaxonomy

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread Alan Gauld

bhaaluu [EMAIL PROTECTED] wrote

 What is the equivalent of JUnit in Python?

I think the nearest equivalent is

 writing my own is probably out the question. Also I'm not familiar 
 with
 Java, and am just learning Python OOP, so I'm not getting much out
 of that one. Sorry. Absolute Beginner here.

Note that Unit testing is orthogonal to OOP.
You can use TDD and unit tests(and should!) when
doing procedural programming just as well.


 Well, most of these were local variables in main() in the procedural
 version of this program. So DataClass() is what I should name such
 a class. I was wondering about that.

While you can use classes that way it leads to a style of
programming called object based rather than object oriented.
It uses objects but the underlying design is still procedural.
Thats why its better to focus on the behaviour of the objects
and add the data attributes needed to support that behaviour.
Remember we communicate with objects by sending them
messages asking them to *do* stuff not to get data out of
them, or at least we should do.
Objects do it to themselves: The Law of demeter.
Ask What does this object do? What data does it need to
achieve that?

 Castle setup in it's own class because it is an object (using the
 model as a real-world object method).

Yes, each object should initialise its own data.
(Albeit maybe based on values passed into the constructor.)

HTH,

Alan G. 


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread Alan Gauld

Alan Gauld [EMAIL PROTECTED] wrote 

 What is the equivalent of JUnit in Python?
 
 I think the nearest equivalent is
 

Oops, I was going top say PyUnit then remembered the name 
had changed but forgot to check out the latest incarnation.
Fortyunately others have done the work for me.

Personally I like the Nose framework that comes with 
TurboGears but even hand written unit tests are no big 
deal in Python - just use asserts and other invariant 
checks and tests etc liberally 

Alan G.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread bhaaluu
On Feb 7, 2008 6:47 PM, Alan Gauld [EMAIL PROTECTED] wrote:

 Alan Gauld [EMAIL PROTECTED] wrote

  What is the equivalent of JUnit in Python?
 
  I think the nearest equivalent is
 

 Oops, I was going top say PyUnit then remembered the name
 had changed but forgot to check out the latest incarnation.
 Fortyunately others have done the work for me.

 Personally I like the Nose framework that comes with
 TurboGears but even hand written unit tests are no big
 deal in Python - just use asserts and other invariant
 checks and tests etc liberally


 Alan G.

PyUnit:
It really doesn't seem to be an absolute beginner technique.
The noun/verb/adjective technique seems to be geared
more towards beginners. I like the idea of that technique.
Perhaps the unit test approach is more for Intermediate
learners, or learners who already have a background in
OOP of some form or another (like Java). I'm just starting out,
so I'm looking at everything that is thrown at me, but quite
frankly, it is really easy for me to see something that is over
my head at this point. If it's over my head, I'll just stall, like
I have in the past, and then I'll have to start this thread over
again later. sigh 8^D

I guess you can tell it's been a long day for me. I've done
some reading, some coding, some experimenting... all in
a day's play for a Hobbyist Programmer. 8^D

I'll take another look at PyUnit tomorrow morning
when I'm fresh.

One thing I'm encouraged by: in Alan's tutorial, he
says that I don't have to see the light to use POOP.
But if I can learn some basic design POOP techniques
from all this, then I'll be happy. After all, I'm a beginner...
you can't get any more basic than that!

Happy Happy Joy Joy.
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-07 Thread Tiger12506
There's a couple of errors in here that no one has addressed yet because the 
question was geared towards programming style... So now I will address them. 
Or undress them, I suppose. ;-)

 #!/user/bin/python
 
From the testing laboratory of:
 b h a a l u u at g m a i l dot c o m
 2008-02-07
 

 import time

 CS = \n*50

This is okay, but it is a little more intuitive to make this
def clrscr():
  print \n*50

so that you can say
clrscr()

because clearing the screen is an action, not a thing that you would 
normally think of printing. The point of python is to make programming 
easier for humans. You defeat it's greatest power by not using it in a style 
that takes advantage of it's ability to mimic the real world. actions 
usually indicate functions.  (This is definitely a style thing. I'm not 
trying to start an argument)

 class TestClass1(object):
 please give me a better name
def __init__(self):
please document me
self.name = 
self.answer = 
self.strength = 20
self.wealth = 45
self.light = 0
self.tally = 0

As mentioned before, data in class should be related to one real (or 
abstract) object, not just a container for random data.

 def main():
tc1 = TestClass1() # instance
tc1.__init__() # invoke method
print CS
N1 = tc1.name
N1 = raw_input( WHAT IS YOUR NAME, EXPLORER? )

This is pointless. When you assign the value of tc1.name (which is ) you 
immediately overwrite it when you say N1 = raw_input(...) What you are 
trying to accomplish without grokking assignment is this.

tc1.name = raw_input(What is your name, explorer?)

# main game loop
while True:
print CS
print ( %s, YOUR STRENGTH IS %d) % (N1, tc1.strength)

Earlier you set N1, but not tc1.name. Either use one or the other.

print ( YOU HAVE $%d) % tc1.wealth
if tc1.light == 0:

Can be
if tc1.light:
  print(The light's on, but no one's home)
else:
  print(It is too dark to see anything)

print ( IT IS TOO DARK TO SEE ANYTHING)
else:
print ( THE LIGHT'S ON, BUT NO ONE'S HOME)
print
print
A = tc1.answer

Again, the same problem with tc1.name. Why are you bothering with A? Please 
realize that you can assign directly

tc1.answer = raw_input(...)

and just use the one variable. This is not C, but Python.

A = raw_input( WHAT DO YOU WANT TO DO? [Q|L]: ) # main game 
 prompt
if A.upper() == Q:
break
if A.upper() == L:
light = raw_input( LIGHT? [0|1]: ) # turn the light on and 
 off
if light == 0 and tc1.light == 0:

What?!? What is the deal? Do you have two different lights? No... then using 
two different light variables does not make sense. Also, the variable 
'light' will never be == 0 unless you hit enter without entering anything 
because raw_input returns a string. 0 != 0

print ( THE LIGHT IS OFF)

I see. You have two seperate variables so that you can determine whether the 
light was off previously. In which case, I suggest you change the variable 
to a more intuitive name, such as 'chosen' or something. To test whether the 
light was on before or not, you should have a method of the class 
islighton() because you are performing an action. Checking to see whether 
the light is on. If this doesn't make sense to you, consider that often 
attributes of a class are not directly accessed. There are even special 
things called properties that define get and set methods of classes... Um, 
disregard that. Too much info. :-)

time.sleep(2)
if tc1.wealth = 0:

You have put this wealth check after the changing of the light. So it is 
possible that someone can change the light after they already have no money.

print
print ( YOU HAVE NO MONEY)
time.sleep(2)
else:
tc1.light = int(light)

Good. You just didn't think of int() in the if check. btw, you aren't going 
to tell anyone when they turn the light on?

tc1.wealth -= 15
else:
print ( INVALID CHOICE)
time.sleep(2)
tc1.tally += 1
tc1.strength -= 5
if tc1.strength = 0:
print ( YOU DIED)
time.sleep(2)
break
print
print ( Final Score:)
print (Tally: %d) % tc1.tally
print (   Wealth: $%d) % tc1.wealth
print ( Strength: %d) % tc1.strength

 if __name__ == __main__:
main()

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-06 Thread Alan Gauld
Tiago Saboga [EMAIL PROTECTED] wrote

 sub types of an abstract superclass. Do NOT use data
 attributes for this, always base inheritance heirarchies
 on behaviour.

 Could you please elaborate on this last sentence? I don't understand
 what you mean, and I feel I may be on this track.

Inheritance heirarchies are the basis of polymorphism in OOP.
Polymorphism is all about methods not data. Therefore to create
useful inheritance heirarchies the key is to find groups of objects
that share the same behaviour (ie method set) even if the internal
data (the attributres) are different.

The classic example of polymorphism is shapes.
Now if you look at the data attributres of a set of shapes: square,
circle, triangle etc they look quite different. (radius v lenxbreadth,
height, angles etc) So from a data perspective they are not good
inheritance candidates. But idf you look at their behaviours - draw,
calculate area, move, intersect etc they are all shared, thus we
can create an abstract superclass with those behaviours. Each
subclass can provide its own internal data and implementt the
methods using that data but the external interface of all shapes
is identical and therefore polymorphiasm can be used.

By contrast if you take some objects that have the same data
but different methods and try to create a superclass you will
simply wind up with a very big class that aggregates all the
methods of all the objects but cannot be used in a polymorphic
way because only a subaset of the methods actually apply to
any given instance.

Thus always base inheriotance on common mbehaviour not on
common data.

I hope that makes it clearer.

-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld 


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-06 Thread bhaaluu
On Feb 5, 2008 3:02 PM, Alan Gauld [EMAIL PROTECTED] wrote:

 One of the earliest ways of doing this has now fallen sonewhat
 out of favour but in practie I find it works quite well for beginners
 is:

 Describe the problem in plain English text(or whatever you
 language is!). Underline the nouns and separate into proper
 and common nouns. Common nouns are likely classes (although
 be careful to check for synonyms - the same class described
 by different nouns) while proper nouns are likely to be instances
 of classes (which classes may or may not be in your list of
 common nouns) Identify the common noun (class) that applies
 and add to your list.

This sounds like a good suggestion! I've already started, and have a rough
draft. I still need to knock the rough edges off the description. How
detailed do you make your description? Do you write an overview
that isn't very detailed, or do you describe every detail you can
think of? (My rough draft is quite detailed because I have just finished
writing the procedural program, and have all the details in my head.)

Actually, writing a description of the problem in Plain English is part
of designing any computer program (according to some old programming
texts I have). This is why beginning computer programmers should stay
awake in English class, and pay attention to grammar!

 Now go through and identify the verbs and adjectives in the text.
 Assign each to a noun. Verns are potential methods of the classes
 and adjectives are potential attributes.

Noted: potential


 The end result is a candidate set of classes with potential
 methods and attributes. Now try linking them together to identify
 relationships. Don't be surprised if not all classes are related to
 others - you will usuially identify more classes than you need
 and some classes will be demoted to attributes of other more
 significant classes. And a few attributes may get promoted to
 classes in their own right.

I had a 'testing' directory when I wrote the procedural version of the
program. I tested snippets of code to see if they would work, before
putting them in the main program. I can see that a similar 'testing'
directory will be well used when designing this POOP version. 8^D

 Once you have your candidate classes pick a few that look
 like they will be core to the problem and try to work through
 some scenarios focussing on the interactions between the
 objects. At this point its often good to think of the objects
 in physical terms - as if you were building a mechanical
 model of the problem rather than a software version. What
 kinds of signals or messagews would you send to each
 object and how would each object interact with those
 around it

This is why I chose the Text Adventure Game as a learning program.
It is full of objects that can be thought of in physical terms! I'm not
quite clear how they will message each other (yet), but that will
probably become clearer as I work through this.

 Don't at this stage worry too much about inheritance.
 Focus on function. If you find that several classes have
 the same or similar methods then consider if they are
 sub types of an abstract superclass. Do NOT use data
 attributes for this, always base inheritance heirarchies
 on behaviour.

Noted.

 Worth a try. It will miss many OOP tricks but as a starter
 methodology it is how millions of OOP programmers began.
 As you gain experience you will identify common abstract
 patterns. Once that starts then go and read the design
 patterns book by Gamma et al.

This is exactly the kind of thing I was looking for
I'm sure I'll have more questions as I go along.

 Thats how I'd do it, I'm sure others will suggest other
 approaches.

 --
 Alan Gauld
 Author of the Learn to Program web site
 http://www.freenetpages.co.uk/hp/alan.gauld

Thank you Alan!
Happy Programming!
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-06 Thread Tiago Saboga
On Wed, Feb 06, 2008 at 08:58:09AM -, Alan Gauld wrote:
 Thus always base inheriotance on common mbehaviour not on
 common data.
 
 I hope that makes it clearer.

Thanks Alan, it's clear now. And now I know that this is not one of
the mistakes I am making ;)

Tiago Saboga.
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-06 Thread bhaaluu
On Feb 5, 2008 3:02 PM, Alan Gauld [EMAIL PROTECTED] wrote:

 Describe the problem in plain English text(or whatever you
 language is!).
 --
 Alan Gauld
 Author of the Learn to Program web site
 http://www.freenetpages.co.uk/hp/alan.gauld


Here is my description, in plain English.

Text Adventure Game Requirements:
 1. The Explorer enters her name at a prompt.
 2. Other things are initialized at this point.
 3. The layout of the Castle is defined.
 4. Treasure is placed in rooms in the Castle.
A. Treasure is distributed randomly to four rooms.
B. Treasure is placed in two specific rooms.
 5. Four Monsters are randomly distributed to four rooms in the Castle.
A. No monsters should be placed at Entrance or Exit.
B. Each monster has a name.
C. Each monster has a Ferocity Factor / Danger Level.
 6. She has 100 strength and $75 wealth to start with.
A. Strength is decremented 5 for each prompt entry.
   1. If strength equals zero:
  a. She dies.
  b. Final score displayed.
  c. Game over.
B. Strength can be incremented by consuming food.
C. Wealth can be used to buy things in QuarterMaster's Store.
D. Wealth can be incremented by finding and picking-up treasure.
 7. She does not have food, weapons, armor, magic, or light.
 8. She starts at the Entrance to the Castle (Room 6).
 9. She cannot see anything without a light.
10. She enters commands at the prompt in order to:
A. Move in six directions [N,S,E,W,U,D]:
   1. Move in indicated direction.
   2. Informed she cannot move in indicated direction.
   3. Her strength is decremented 5 each move.
   4. The tally of moves is incremented 1 each move.
B. Access the Provisions  Inventory menu [I]:
   1. She must have some wealth to access the PI menu.
   2. She can purchase items from the menu:
  a. Light is 0 or 1.
  b. Weapons: Axe / Sword is 0 or 1.
  c. Food units.
 1. She is told how many units of food she has.
 2. She is asked how many units of food she wants to buy.
  d. Magic amulet.
  e. Armor.
   3. Wealth is decremented after each purchase.
  a. She is informed when she has no money, and exited from the store.
  b. She loses everything except strength and food,
 if she tries to spend more wealth than she has.
C. She can pick-up treasure [P].
   1. She cannot pick-up treasure if she cannot see it (she needs light).
   2. The treasure will remain in the room if not picked-up.
D. She can run from a monster [R].
   1. She may be asked where she wants to flee to (direction).
   2. She may be told she must stand and fight (random decision).
E. She can fight a monster.
   1. Wearing armor increases her chance of success.
   2. If she has a weapon, she must fight with it.
   3. If she has two weapons, she is asked which one she wants to use.
   4. If she has no weapon(s), she must fight bare-handed.
  a. The Explorer or the monster may attack first (random decision).
  b. The Explorer or the monster may wound the other (random decision).
  c. The Explorer or the monster may defeat the other.
 1. Strength is decremented from the Explorer during the fight.
 2. Ferocity Factor is decremented from the monster during
the fight.
11. She can consume food [C].
A. She must have food to consume
   1. She is told how many units of food she has.
   2. She is asked how many units of food she wants to eat.
12. She can use the Magic Amulet [M].
A. She must have the Magic Amulet in her possession.
B. The Magic Amulet will move her to a random room in the Castle.
   1. It should not move her to the Entrance or Exit.
13. The game ends when she exits the Castle (finds Room 11).
A. Exit message is displayed.
B. Final Score is displayed.
   1. Final score depends on several factors:
  a. Strength, wealth, tally, food, number of monsters killed.

Now the hard part: grammar.
Happy Programming!
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-06 Thread Alan Gauld
bhaaluu [EMAIL PROTECTED] wrote 

 Here is my description, in plain English.
 
 Text Adventure Game Requirements:
 1. The Explorer enters her name at a prompt.
 2. Other things are initialized at this point.
 3. The layout of the Castle is defined.
 4. Treasure is placed in rooms in the Castle.

Actually thats not really plain English its a very structured 
English. In fact it approaches procedural pseudo code!

Its possibly a little too detailed too.

I'd go for a more free-form paragraph or two(at most) something 
like:
--
I want to build a text adventure game based around 
an explorer moving around a castle with multiple rooms,. In 
each rooms there could be various items of treasure or monsters. 
To win the game the explorer has to collect as much treasure 
as possible and defeat as many monsters as possible. Treasure 
is worth points and the expolorer starts off with a given amount 
of strength and points. ..

Because its a text game the interface will consist of a series 
of input prompts with responses and printed status messages.
The game is over when.
---

That should be shorter and less likely to predispose your thinking 
to a particular approach - such as when the initialisation takes 
place, or how many rooms or premature consideration of the 
command structures etc. These things should emerge as you 
create the object definitions and interactions. The initial aim is 
only to find the half dozen to a dozen key classes top get started. 
Other classes will emerge as you progress, and some of the 
original candidates may merge into others or be discarded.

And don't forget that there could well be a game class/object to 
control the overall flow of the game and coordinate the actions 
of the other objects. For example the prompt/response/display 
mechanism might be part of the game class (and they might 
be classes too!). This would maximise reuse of the compnent 
objects within a different game framework ( a GUI fort instance) 
later.

HTH,

-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-06 Thread bhaaluu
Thank you Alan.

This helps tremendously! I had gone to your OOP tutorial and read it
over (again) and the closest thing I could find on that page was
the Bank Account example that had a list of things a bank account
might be expected to do. So away I went, making a list.

The problems with that approach surfaced as soon as I started
trying to identify the nouns (potential classes and instances),
adjectives (potential attributes) and verbs (potential methods).

I'm making mistakes, but at least that shows that I'm trying. If nothing
else, I now know what doesn't work. 8^D Actually, I'm not expecting
to get this done today. It may take awhile. From my past experience,
that is how the design process goes. But if I can learn how to do this,
I'm pretty sure it will save a lot of time when I work on future projects.

Back to the drawing board!
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]

On Feb 6, 2008 12:06 PM, Alan Gauld [EMAIL PROTECTED] wrote:
 bhaaluu [EMAIL PROTECTED] wrote

  Here is my description, in plain English.
 
  Text Adventure Game Requirements:
  1. The Explorer enters her name at a prompt.
  2. Other things are initialized at this point.
  3. The layout of the Castle is defined.
  4. Treasure is placed in rooms in the Castle.

 Actually thats not really plain English its a very structured
 English. In fact it approaches procedural pseudo code!

 Its possibly a little too detailed too.

 I'd go for a more free-form paragraph or two(at most) something
 like:
 --
 I want to build a text adventure game based around
 an explorer moving around a castle with multiple rooms,. In
 each rooms there could be various items of treasure or monsters.
 To win the game the explorer has to collect as much treasure
 as possible and defeat as many monsters as possible. Treasure
 is worth points and the expolorer starts off with a given amount
 of strength and points. ..

 Because its a text game the interface will consist of a series
 of input prompts with responses and printed status messages.
 The game is over when.
 ---

 That should be shorter and less likely to predispose your thinking
 to a particular approach - such as when the initialisation takes
 place, or how many rooms or premature consideration of the
 command structures etc. These things should emerge as you
 create the object definitions and interactions. The initial aim is
 only to find the half dozen to a dozen key classes top get started.
 Other classes will emerge as you progress, and some of the
 original candidates may merge into others or be discarded.

 And don't forget that there could well be a game class/object to
 control the overall flow of the game and coordinate the actions
 of the other objects. For example the prompt/response/display
 mechanism might be part of the game class (and they might
 be classes too!). This would maximise reuse of the compnent
 objects within a different game framework ( a GUI fort instance)
 later.

 HTH,

 --
 Alan Gauld
 Author of the Learn to Program web site
 http://www.freenetpages.co.uk/hp/alan.gauld


 ___
 Tutor maillist  -  Tutor@python.org
 http://mail.python.org/mailman/listinfo/tutor

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-06 Thread bhaaluu
On Feb 6, 2008 12:06 PM, Alan Gauld [EMAIL PROTECTED] wrote:
 bhaaluu [EMAIL PROTECTED] wrote

  Here is my description, in plain English.
 
  Text Adventure Game Requirements:
  1. The Explorer enters her name at a prompt.
  2. Other things are initialized at this point.
  3. The layout of the Castle is defined.
  4. Treasure is placed in rooms in the Castle.

 Actually thats not really plain English its a very structured
 English. In fact it approaches procedural pseudo code!

 Its possibly a little too detailed too.

My first try didn't work. I'm going to try again.
I'm intrigued with the idea that the nouns, verbs,
and adjectives can indicate possible classes,
instances, methods, and attributes. While I'm
familiar with the objects in this TAG example,
I'd like to have a way to approach something
that I'm not as familiar with. I like the idea of
this technique. It seems like it should work
with just about anything that can be modelled
as an object.

I have a tendancy to think about
things as actual objects (but probably not OOP
objects -- more like real objects, like a vase).
I also like techniques.

I know this much:

Explorer: has strength  wealth, can carry weapons  food,
can wear armor, can pick-up treasure, can fight monsters,
can wound monsters, can defeat monsters, can move from
room to room.

Monster: can be anywhere, has Ferocity Factor / Danger Level,
can fight Explorer, can wound Explorer, can defeat Explorer.

Treasure: can be picked-up, can be in any room in Castle
(except entrance and exit).

Castle: contains interconnected rooms, has three levels.

Rooms: room has door(s), door(s) connect to other rooms,
room has description, can contain treasure, can contain monster.

The trick is to take all that stuff, and figure out what the classes
are, the instances, the methods, and the attributes. So it seems
I need to write something descriptive about exploring the above.
Subject, verb, adjective object.

I must start somewhere! 8^D
The above is much smaller than my previous pseudocode attempt.


 I'd go for a more free-form paragraph or two(at most) something
 like:
 --
 I want to build a text adventure game based around
 an explorer moving around a castle with multiple rooms,. In
 each rooms there could be various items of treasure or monsters.
 To win the game the explorer has to collect as much treasure
 as possible and defeat as many monsters as possible. Treasure
 is worth points and the expolorer starts off with a given amount
 of strength and points. ..

 Because its a text game the interface will consist of a series
 of input prompts with responses and printed status messages.
 The game is over when.
 ---

 That should be shorter and less likely to predispose your thinking
 to a particular approach - such as when the initialisation takes
 place, or how many rooms or premature consideration of the
 command structures etc. These things should emerge as you
 create the object definitions and interactions. The initial aim is
 only to find the half dozen to a dozen key classes top get started.
 Other classes will emerge as you progress, and some of the
 original candidates may merge into others or be discarded.

 And don't forget that there could well be a game class/object to
 control the overall flow of the game and coordinate the actions
 of the other objects. For example the prompt/response/display
 mechanism might be part of the game class (and they might
 be classes too!). This would maximise reuse of the compnent
 objects within a different game framework ( a GUI fort instance)
 later.

 HTH,

 --
 Alan Gauld
 Author of the Learn to Program web site
 http://www.freenetpages.co.uk/hp/alan.gauld


 ___
 Tutor maillist  -  Tutor@python.org
 http://mail.python.org/mailman/listinfo/tutor


Happy Happy Joy Joy
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-06 Thread Alan Gauld
bhaaluu [EMAIL PROTECTED] wrote 

Let me preface this message by saying that I've never written 
a TAG before - either procedurally nor using OOP. so I don't 
know if the following approach is a good way to go or not. 
However it's where I feel things moving...

 I have a tendancy to think about
 things as actual objects (but probably not OOP
 objects -- more like real objects, like a vase).

But thats the right way to go. The whole point of OOP is 
that you are trying to simulate the real world objects. 
Thats why people who haven't been trained in classical 
programming techniqiues usually find OOP much 
easier to pick up than experienced programmers do.
Its logically more sensible to say move a table in a 
direction for a distance than to change the x,y 
coordinates explicitly!

 Explorer: has strength  wealth, can carry weapons  food,
 can wear armor, can pick-up treasure, can fight monsters,
 can wound monsters, can defeat monsters, can move from
 room to room.

A good start so Explorer looks like a class with two scalar 
attributes: strength and wealth. Also a number of lists of 
objects - weapons, food, treasure and maybe armor.
Looks like we might have a set of methods to pickUp(object)
and to wear(armor) and maybe some test methods
hasWeapon(weapon), isWearing(armor) etc.
Also we have some methods around fighting, BUT...
We are interested in what we can do TO the objerect 
not what it does to other objects (at least at this point).
So rather than fighting a monster maybe the monster 
can be fought - ie the fight method is a method of monster?
Except

 Monster: can be anywhere, has Ferocity Factor / Danger Level,
 can fight Explorer, can wound Explorer, can defeat Explorer.

It looks like the same applies to monsters and Explorers. 
So maybe both Monster and Explorer are subclasses of 
a Fighter because they share the same methods.
Now we can have a battle between two fighter objects - and 
this could allow the game to be extended to allow monsters 
to fight monsters and explorers to fight explorers, almost 
for free!

class Fighter(object):
def fight(self, fighter)
def attack(self, weapon)
def repulse(self, weapon)
def isKilled(self)
def currentStrength(self)

Notice that one of the things that seems to come out of this 
is that maybe the strength attribute and the list of weapons 
belongs in the fighter class? Or maybe not if monsters 
don't have weapons - a design decision...

Now we can make a stab at how the fight metjod might work:

def fight(self, fighter):
 weapon = self chooseWeapon()
 fighter.attack(weapon)
 if fighter.isKilled():
self.strength += fighter.value

And from this we could maybe do the attack method too:

def attack(self,weapon):
  if self.canRepulse(weapon):
 self.repulse(weapon)
  else:
  self.strength -= weapon.value
  if self.strength  0:
 self.die()

And this reveals some new attributes and methods we 
can add, and also probably some ideas for how to write 
the repulse method too...

And by constantly repeating this cycle of invent a bit, 
write a bit, test a lot we gradually build up the individual 
classes. Remember the  prompt is your friend for 
testing these things. Create a few instances of fighters 
and weapons and get them to fight each other using 
the prompt.

When you stop being sure of where to go, go back to 
your text description and look for more clues about 
other objects that might help.

As I say, I don't actually know if the above aproach will 
really work for a TAG but it looks worth a try. But one 
of the beauties of OOP is that each object is a mini 
program that can be played with and experimented 
with at the  prompt so you find out what works 
and what doesn't very quickly.

HTH,

-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-06 Thread Kent Johnson
bhaaluu wrote:
 How do you design POOP? What are the guidelines you keep in mind
 to design good POOP? Can an absolute beginner learn to design POOP?

I have mostly stayed out of this thread for lack of time and because 
Alan is doing a great job, but I think I will chime in a bit because 
this is an area where Alan and I have very different styles.

Let me say that I don't mean any disrespect for Alan or his approach, I 
just have a different point of view.

Also I will say that converting a procedural program to OO 'just 
because' is not necessarily a good idea. Not every program is improved 
by OOP. In your case, it probably will be though.

I tend to work from small pieces to larger ones and let the design grow 
from the needs of the code, rather than from considerations of nouns and 
verbs in the spec.

I think for me the primary drivers are data structure and functionality. 
For example, maybe I need a way to represent a room. I might start with 
a simple list or tuple and write some code that works with rooms. Soon I 
get tired of having to use subscripts all the time so I make a simple 
container class Room to hold the data. Then I will find bits of 
functionality - functions - that work with the room data; they become 
methods of the Room class.

One piece at a time the code grows. Each new piece of functionality 
imposes new requirements on the design and the design may change to 
accommodate it. Design a little, code a little, repeat...
http://personalpages.tds.net/~kent37/stories/3.html

Once and Only Once - aka Don't Repeat Yourself - is one of the best 
principles of design. Whenever you are tempted to copy/paste code or 
data, ask yourself how you could change the design to avoid the copying. 
You can discover many useful design techniques by applying DRY. More here:
http://personalpages.tds.net/~kent37/stories/00012.html

Sensitivity to code smells is another good way to discover when your 
design needs to change. Martin Fowler's book Refactoring popularized 
this term. It has a chapter that explains the code smells and points out 
ways to fix them. An abbreviated version is available here:
http://wiki.java.net/bin/view/People/SmellsToRefactorings

The writings of Robert C Martin have taught me a lot about good design 
and agile development. They don't all apply to Python - many design 
patterns that make sense in C++ or Java are not needed in Python - but 
the principles still hold. A lot of his work is available on-line:
http://objectmentor.com/resources/publishedArticles.html

http://objectmentor.com/resources/articles/Principles_and_Patterns.pdf 
might be a good starting point.
http://objectmentor.com/resources/articles/xpepisode.htm attempts to 
give the flavor of agile, test-driven development.

I don't use the command-line interpreter much, I do a lot more work in 
unit tests. In test-driven development (TDD), if you decide you want a 
Room class, the first thing you do is create a unit test for the class. 
The test will fail, because the class doesn't exist, so you next write 
the class and make the test pass. Then add another (failing) test for 
the next bit of functionality, then implement it and make the test pass. 
Continue as needed. I have written a little more about this here:
http://personalpages.tds.net/~kent37/stories/7.html

HTH,
Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-05 Thread Marc Tompkins
On Feb 5, 2008 5:46 AM, bhaaluu [EMAIL PROTECTED] wrote:
 What I'm interested in is the thought processes and/or
 guidelines that Tutors employ when they sit down to design a POOP.

Whenever I have a few free minutes and a desire to contemplate the
infinite (Hah!), I surf over to the C2 wiki.  I don't know the
official name of the thing, I don't even know which page (if any) is
supposed to be the home page.  Rather, I surf around it the same way
I did the dictionary when I was a kid - just let one link lead to
another.  Officially it's about refactoring - which basically means
tuning-up a suboptimal design, with the implicit assumption that all
designs are suboptimal and could be improved.  But it's also a great
place to see a bunch of very smart programmers opine on exactly what a
good design is in the first place.  The principles of OnceAndOnlyOnce
and Don'tRepeatYourself, for instance, speak directly to the questions
you're asking.

I must say that I find the visual design, and the editing style,
incredibly infuriating.  Not every contributor signs his/her
submission, so it's not always clear where one ends and another
begins.  Did I mention it's ugly?  But it's fascinating stuff, and I
feel it's made me a better programmer.  Most of the programming
examples are in Java {ick!}, some are in Smalltalk; I think I've seen
some Lisp; I have yet to see an example in Python.  But the code is
all pretty readable (which is, after all, one of the principles
they're trying to get across.)

The Code Smells page is as good a starting place as any:
http://c2.com/xp/CodeSmell.html

Enjoy!  (And by the way - if you find any paragraphs particularly hard
to follow {I certainly have!}, don't kill yourself.  Read on a bit
further down the page.  Generally another contributor will have
restated the same argument in more accessible terms - remember that
great programmers are not necessarily great essayists, and vice
versa.)

--
www.fsrtechnologies.com



-- 
www.fsrtechnologies.com
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-05 Thread bhaaluu
On Feb 5, 2008 1:13 PM, Marc Tompkins [EMAIL PROTECTED] wrote:

 On Feb 5, 2008 5:46 AM, bhaaluu [EMAIL PROTECTED] wrote:
  What I'm interested in is the thought processes and/or
  guidelines that Tutors employ when they sit down to design a POOP.


 The Code Smells page is as good a starting place as any:
 http://c2.com/xp/CodeSmell.html

 --
 www.fsrtechnologies.com

This page looks good:

http://c2.com/cgi/wiki?PrinciplesOfObjectOrientedDesign

8^D
-- 
b h a a l u u at g m a i l dot c o m
You assist an evil system most effectively by obeying its
orders and decrees. An evil system never deserves such
allegiance.  Allegiance to it means partaking of the evil.
A good person will resist an evil system with his or her
whole soul. [Mahatma Gandhi]
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-05 Thread Kent Johnson
bhaaluu wrote:
 POOP: Python Object Oriented Programming/Programmer/Program(s)

POOP = borderline offensive and definitely annoying. Maybe you don't 
know that poop is a synonym for excrement? Is that what you are trying 
to learn?

 Now I am interested in learning how to DESIGN an object-oriented version
 of the game in Python. All my Python tutorials show me the mechanics of
 how to MAKE classes. What I'm interested in is the thought processes and/or
 guidelines that Tutors employ when they sit down to design a POOP.

 From the archives:
http://thread.gmane.org/gmane.comp.python.tutor/29876
http://thread.gmane.org/gmane.comp.python.tutor/39443/focus=39489
http://thread.gmane.org/gmane.comp.python.org.baypiggies/2857/focus=43197

Also:
http://personalpages.tds.net/~kent37/stories/00014.html

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] designing POOP

2008-02-05 Thread Tiago Saboga
On Tue, Feb 05, 2008 at 08:02:19PM -, Alan Gauld wrote:
 bhaaluu [EMAIL PROTECTED] wrote
 
  Now I am interested in learning how to DESIGN an object-oriented 
  version

The question was very interesting, and so where the answers.

 Don't at this stage worry too much about inheritance.
 Focus on function. If you find that several classes have
 the same or similar methods then consider if they are
 sub types of an abstract superclass. Do NOT use data
 attributes for this, always base inheritance heirarchies
 on behaviour.

Could you please elaborate on this last sentence? I don't understand
what you mean, and I feel I may be on this track.

Thanks,

Tiago Saboga.
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor