[Tutor] Re: Classes!Classes!Classes!

Christian Tismer tismer@appliedbiometrics.com
Wed, 22 Dec 1999 17:34:12 +0100

Lessee :-)

Christopher Grove wrote:
> I have just started investigating Python, and want to jump in with class
> questions (to verify if I have gotten to the 'aha!' stage mentioned
> earlier.

First of all, I highly recommend to learn a lot about
tuples, lists, dicts, and a couple of standard modules
before diving into classes. Not that they are too difficult,
but everything ismuch easier when you have your tools ready.
For instance, you should not need to wonder what a dictionary
is, when I advise you to look at your class's __dict__ 
at some time.

> Can classes be composed of other (sub)classes?


> Can classes be composed of multiple copies of the same (sub)class?

There cannot be multiple copes of a subclass.
It is the same subclass, or it is a different subclass.
If it is the same, then it is identical.

> [I apologize for bastardizing any terminology here, I am trying to put
> it in my own words (because they are what I understand best).]
> My self-determined example is house design and definition:

What you need to build your house is a bit different.
The class system is not meant to build actual objects
with classes as building blocks to fit together.

What you need are instances (rooms) which are inserted into
your house instance, as attributes. Houses do not inherit from
rooms or vice versa, they "have" them. This is acquisition,
not inheritance.

> House(class)
>         Living room(class)
>                room(class)[1]
>                light(class)[0..n]
>                lr furniture  (or would I have multiple classes here,
> sofas, chairs, tables, etc)
>                color (or would these be attributes of the floor,
> ceiling, walls)
>         Kitchen(class)
>                room(class)
>                light(class)
>                kitchen furniture
>                kitched appliances
>                .
>         Bathroom(class)[1..n]
>                .
>         Dining room(class)
>                .
>         Bedroom(class)[1..n]
>                room(class)
>                light(class)
>                bedroom furniture
>                .
>                .
>                Room(class)
>                    Ceiling(class)[1]
>                    Floor(class)[1]
>                    Wall(class)[1..n]
>                    description
>                    dimensions
>               .
>               .
>                    Ceiling(class)
>                        Composition
>                        Color
>                        Light(class)[0..n]
>                        Fan(class)[0..n]
>                        Dimension
>                    Wall(class)
>                        Composition
>                        Color
>                        Dimension
>                        Window(class)[0..n]
>                        Door(class)[0..n]
>                        Light(class)[0..n]

class Room:
    # static properties
    def __init__(self, arg1, arg2...):
        # dynamic, instance specific initilization

class Bathroom(room):
    # like all rooms, but also with this:
    def __int__(self):
        Room.__init__(self) # inerited init
        self.occupied = 0

    def occupy(self, who):
        self.occupied = who   # no time for a better example :-)

class Building:
    # set some generic default methods, perhaps

def House(Building):

# now, without a special class, I assemble the house, simply by
# adding pieces as attributes.
# Of course one could invent a factory class which does this,
# according to a plan. Try this as an exercise...

# simply building a house:

myHouse = House()
myHouse.bath = Batchroom()
mHouse.livingroom = Room()  
# ...

> Lights can be part of the ceiling or wall, or free standing.  Can the
> (sub)class defintion be placed at different levels in the class
> heirarchy?

I think this would abuse the class idea, if possible at all.
Where you put your lights in your object depends on what you
intend to do on lights. Their position at other objects need
not, but can be useful.
You could attach a light instance as an attribute of an object,
perhaps a wall if that is part of a room.
You could then write a method which gives you a list of all
lights in your house, or you inquire the rooms each.
That's your design problem. You need to play with that
and figure out.
But it has very few to do with inheritance. These are
attributes. Classes do not express "thing a contains thing b",
they express "thing b is like thing a, but has the following
different/additional properties".
Classes are an abstract concept. It does not deal with your house
directly, and with its particular rooms, walls and lights, but
it tells "about houses".
You build it by contructing instances.

> Do I have to (should I) segment walls (i.e. composition, part of the
> wall painted, part wall papered, or part painted and part wainscoated,
> or part ...)?

That's a matter of taste. Just make sure that you can pla with
rooms as a whole, without having to deal with the walls. And with
walls without having to care about wall paper.

> I suppose if I were designing a mansion, I'd have the opportunity for
> multiple kitchens, etc.

Yes. And then you will recognize that this is not always a
hierarchical system. In some houses, several parties are sharing
two kitchens, and "belongs to" is not well-defined.
Try to avoid strong hierarchy, since it will break anyway.
It does make sense to enumerate and name the rooms of the house.
If i tis of interest, their size can be kept as attributes, and
the overall layout can be modelled by which walls are shared
for instance.
For starting, make everything as simple as possible, and think
of what you are going to ask your house before you build it.
There are so many possibilities, that you chance to get the wrong
model at the first time is very likely.

Again at your "multiple copies of the same subclass":
What you mean is many similar rooms, with many similar but
different walls.
This should be done with a decent set of classes,
and all your objects are instances. The "Multiple copy" issue
is solved by instances, since a class can produce as many
objects of that kind as you like.
Then, you need to insert them into your house, as attributes

[ myHouse.someroom = Room() ]

or as elements of other structures:

myHouse.rooms.append( Room() )

You can assemble your parts before of after inserting them:
someRoom = Room():
# call some fuctions to modify the room, or
# do it simply in this direct manner:

someRoom.size = 40 # square meters

# now add it to the house

myHouse.livingroom = someRoom
myHouse.livingroom.desk = Desk(color="brown")

This is a matter of taste.
Try it and get a feeling of it.

cheers - chris

Christian Tismer             :^)   <mailto:tismer@appliedbiometrics.com>
Applied Biometrics GmbH      :     Have a break! Take a ride on Python's
Kaiserin-Augusta-Allee 101   :    *Starship* http://starship.python.net
10553 Berlin                 :     PGP key -> http://wwwkeys.pgp.net
PGP Fingerprint       E182 71C7 1A9D 66E9 9D15  D3CC D4D7 93E2 1FAE F6DF
     we're tired of banana software - shipped green, ripens at home