[Tutor] Classes: global name not defined
Alan Gauld
alan.gauld at btinternet.com
Thu Sep 13 05:56:58 CEST 2007
"Ara Kooser" <ghashsnaga at gmail.com> wrote
> File "/Users/ara/Documents/yeast/oop_yeast_nocaps.py", line 87, in
> <module>
> first_instance.print_world()
> File "/Users/ara/Documents/yeast/oop_yeast_nocaps.py", line 40, in
> print_world
> m, n = world['dimensions']
> NameError: global name 'world' is not defined
>
> I understand that the error refers to the method print_world(). In
> the
> instance before first_instance.print_world() I define what world is
> but that is not being carried over to the print_world method. In the
> print world method
You need to work on your terminology. You are not defining world
anywhere in any instance. You are calling methods of the instance.
But the real problem lies inside the definition of the class methods.
> class World:
> #What makes this a world
>
> def __init__(self,name):
> self.name = name
> #Add other things later
You should probably define world here
self.world = ???? whatever
> def percolation(self,perc):
> perc = float(perc)
This is forgotten as soon as the method ends.
And you don;t use it anywhere else in the method.
Are you sure you don't mean
self.perc = float(perc)
> randval = random.random()
> if randval > perc:
> return EMPTY
> else:
> return YEAST
> def random_world(self):
> #Constructs random world of size MxN
> world = {}
And again this is lost as soon as the methjod ends.
It should be
self.world = {}
except that since its initialisatoon it would be better in
the __init__ method. Thats what its for!
> for j in range(n):
> for i in range(m):
> world[i, j] = self.percolation(perc)
> world['dimensions'] = (m, n)
> return world
In this case you return world but you don't store it in
your main code, so it is still lost.
> def print_world(self):
> #Prints out a string representation of a world.
> m, n = world['dimensions']
And because world ghas never been set anywhee outside
the random_world() method this fails. You should be
accessing self.world. here.
> for j in range(n):
> for i in range(m):
> print world[i, j],
and here...
> print
>
> def add_yeast(self):
> #Allows the user to add a yeast cell at point m,n
> m,n = world['dimensions']
and here
> new_world = copy.copy(world)
>
> counta = 0
> print "The upper left corner is the point (0,0)"
> yy = raw_input("How many yeast cells do you wish to add?")
> yy = int(yy)
>
> while counta<yy:
> i = int(raw_input("Please enter a m value for the yeast
> cell."))
> j = int(raw_input("Please enter a n value for the yeast
> cell."))
>
> new_world[i,j] = YEAST
> for j in range(n):
> for i in range(m):
You just got i.j from the user but now you are throwing away their
input and overwriting it with the values from the for loop. I assume
thats an error?
> world[i,j]=new_world[i,j]
and here...
>
> counta = counta+1
>
> def debug(self):
> print self.name
>
>
> ##########################################################
> #Start of prgram
> ##########################################################
>
> first_instance = World("small_world")
> #first_instance.debug()
>
> raw_input("Please press return to start the program.")
>
> perc = raw_input("Please enter a thresold between 0-1 for the
> population.")
> first_instance.percolation(perc)
>
> n = int(raw_input("Please enter a n dimension. "))
> m = int(raw_input("Please enter a m dimension. "))
These global variables are accessed from the class, it woyld be safer
and more readable to put them into the init method and make
them attributes which can then be accessed with self.m, self.n
Its slightly more typing but makes the code more readable and more
reliable.
> first_instance.random_world()
> first_instance.print_world()
>
> first_instance.add_yeast()
HTH,
--
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld
More information about the Tutor
mailing list