Brian van den Broek wrote:
In an earlier version, instead of the run_world() method I now have, I
put the following within my class definition and after (i.e. outside of)
the method defs:
.>    while self.current_generation > self.total_generations:
.>        time.sleep(self.sleep_interval)
.>        self.update_world()
.>        self.print_world()

which caused this:

Traceback (most recent call last):
   File "D:\Python Files\foogame_of_life.py", line 3, in -toplevel-
     class life_world:
   File "D:\Python Files\foogame_of_life.py", line 76, in life_world
     while self.current_generation > self.total_generations:
NameError: name 'self' is not defined

That surprised me -- I'd have guessed that within a class, self was
everywhere defined, and not just within methods.

self is just another method parameter. OK not quite, but it is a method parameter and it is only bound within the scope of the method. There is nothing magic about the name, either; it is just a (strong) convention.


In fact, by using a different name for self and the magic of lexical scoping and closures, you can do something very much like Java inner classes - make a nested class that has access to all the attributes of the enclosing class.

This is off-topic and a bit twisted, but I'm not going to let that stop me:

''' Make a nested class that has access to the attributes of its parent class 
'''
class Outer:
    def __init__(outerSelf, x):
        outerSelf.x = x

    def makeNested(outerSelf, x):
        class Nested:
            def __init__(innerSelf, x):
                innerSelf.x = x

            def showX(innerSelf):
                print 'outer x is', outerSelf.x
                print 'inner x is', innerSelf.x

        return Nested(x)

o = Outer(3)
n = o.makeNested(5)

n.showX()

o.x = 22
n.showX()

################
prints:

outer x is 3
inner x is 5
outer x is 22
inner x is 5

Kent


Clearly, I'm confused about something.

Anyway, thanks for reading. Best to all,

Brian vdB


------------------------------------------------------------------------

# pylife.py
# Version 0.1
# Brian van den Broek
# [EMAIL PROTECTED]
# 2005-01-06 Thursday 17:41
# Copyright 2005

'''An OOP and ASCII based representation of Conway's Game of Life.
Much of the code was inspired by a post of Danny Yoo's on 2005-01-03 04:11
to the Python Tutor List. (You can find that post by searching the archives at
<http://mail.python.org/pipermail/tutor/>.)

I make no claims to ellegance or efficency -- this is only the second OOP I
have written.'''

import random, time

class life_world:
def __init__(self, X, Y, sleep_interval = 0.5, total_generations = 20):
self.X = X
self.Y = Y self.world = self.seed_world()
self.sleep_interval = sleep_interval
self.total_generations = total_generations
self.current_generation = 0
self.print_world()
def seed_world(self):
'''Constructs a new random world of size XxY.'''


        world = {}
        for j in range(self.X):
            for i in range(self.Y):
                world[i, j] = random.choice((True, False))
        return world

    def print_world(self):
        '''Prints out a string representation of a world.'''

print '\n\nGeneration Number: %s\n' %self.current_generation
print '--'*(self.Y + 1) + '-'
for j in range(self.X):
print '|',
for i in range(self.Y):
if self.world[i, j]:
print 'X',
else:
print ' ',
print '|'
print '--'*(self.Y + 1) + '-'
def count_neighbours(self, cell):
'''Returns the number of live neighbours to this one.


        'neghboUrs because I'm Canadian, eh.
        '''
        live_count = 0
        i,j = cell
        for i_delta in [-1, 0, 1]:
            for j_delta in [-1, 0, 1]:
                if (i_delta, j_delta) == (0, 0):
                    continue
                try:
                    # To deal with the edges of the matrix, where the
                    # deltas can take us out of bounds.
                    if self.world[i+i_delta, j+j_delta]:
                        live_count += 1
                except KeyError:
                    pass
        return live_count

    def cell_will_change(self, cell):
        '''Returns True if a cell will change, False otherwise.'''
        change = False
        if self.world[cell] and not self.count_neighbours(cell) in (2,3):
            change = True
        if not self.world[cell] and self.count_neighbours(cell) == 3:
            change = True
        return change

    def get_changed_cells_list(self):
        '''Returns a list of cells that will change in the next generation.'''

        changed_cells_list = []
        for c in self.world:
            if self.cell_will_change(c):
                changed_cells_list.append(c)
        return changed_cells_list

    def update_world(self):
        '''Produces the next generation world.'''
        self.current_generation += 1
        changed_cells_list = self.get_changed_cells_list()
        for c in changed_cells_list:
            self.world[c] = not self.world[c]

    def run_world(self):
        while self.current_generation < self.total_generations:
            time.sleep(self.sleep_interval)
            self.update_world()
            self.print_world()

if __name__ == '__main__':
    world = life_world(7, 7)
    world.run_world()



------------------------------------------------------------------------

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

Reply via email to