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