Re: [Tutor] How to replace instances

2008-09-29 Thread Kent Johnson
Replying to the list..

On Mon, Sep 29, 2008 at 12:43 AM, Steve Collins <[EMAIL PROTECTED]> wrote:
> Sorry it took me so long to respond; I haven't been able to afford any time
> to such leisurely pursuits as programming.
> I'm not cc'ing this to the Mailing list, becuase I fear it may get a little
> long.

It's not too long.

>
>> I think you still misunderstand what objects and lists and references
>> are,
>
>
> I agree. :D
>
>>
>>   this misunderstanding is making it hard to for me to
>> understand what you are really trying to accomplish. Perhaps you can
>> give a slightly longer example with real classes and lists, perhaps
>> one that doesn't do what you want, and we can correct it.
>
>
> Alright, this is a pared-down example of my problem. The program I'm trying
> to write is a text-adventure game (seemed like a fun way to learn my way
> around programming)
>
> there are, for example, classes which describe rooms and items:
>
> class Item:
> def __init__(self, name):
> self.name = name
> itemIndex[ name ] = self
> masterIndex.append(self)
>
> class Room:
> def __init__(self, name, items):
> self.name = name
> self.items = items
> masterIndex.append(self)
>
> ## which are initialized as they should appear at the beginning of the game
>
> iBook = Item( "book" )
> rLibrary = Room( "library", [iBook] )
>
> ## when the player enters a room, currentRoom is set to the Room being
> entered into. when the player enters the "take" command and specifies
> "book," and sends itemIndex[ "book" ] (which is iBook) to a function is
> called which goes something like:
>
> takeMethod(takeWhat):
> if takeWhat in currentArea.items:
>  (remove the item from currentArea.items, add it to the player's
> inventory and display "you took whatever")
> else:
>  (display "you cant take that.")
>
> this works very well, and I seem to have created a working text adventure
> game. my new problem is the save/load function
> if the player saves, masterIndex is pickled to save.dat
> when the game starts again the player has the option of loading from
> save.dat.
> I did this so I could avoid having a file for every pickled instance, but I
> can't figure out what to do with the unpickled list.

You should be pickling all the game objects and restore them from the
pickle *instead* of the normal init. The unpickled masterindex should
become the actual masterindex. This contains all the current items and
rooms. Also pickle the player, to save inventory and location and any
other player attributes. Restore the pickled player to the actual
player.

One way to do this would be to
>
> The closest I came to a solution was this:
>
> L = 0
>
> class Item:
> def __init__(self, name):
> if new game:
> self.name = name
> elif load game:
> self.name = loadedList[L].name
> itemIndex[ self.name ] = self
> masterIndex.append(self)
>
> class Room:
> def __init__(self, name, items):
> if new game
> self.name = name
> self.items = items
> elif load game:
> self.name = loadedList[L].name
> self.items = loadedList[L].name
> masterIndex.append(self)
>
> When the game is loaded, the player can't take the book, becuase the
> takeItem function does not find itemIndex["book"] in the current room,
> because itemIndex ["book"] refers to the newly initialized iBook, instead of
> the old iBook.
>
> Even as I was writing the previous sentence, I realized that if I moved
> itemIndex[ self.name ] = self to the "elif load game" condition and changed
> it to "itemIndex[ self.name ] = loadedList[L]" that would fix this
> particular problem. I tried it with the various dictionaries in the game,
> and it does. But in the actual game, the classes refer to each in much more
> complicated ways, which I fear could break this fix. It also feels clumsy,
> to have all these instnaces which have the exact same data as the loaded
> ones, but don't actually refer to them.
>
> another solution I thought of was this:
>
> if new game:
> iBook = Item( "book" )
> rLibrary = Room( "library", [iBook] )
> elif load game:
> L = 0
> iBook = loadedLis[L]
> L +=1
> rLibrary = loadedList[L]
> etc., etc.

if new game:
  # normal object initialization
elif load game
  # load masterlist from pickle file
>
> I think this would work well, but, again, it seems clumsy and would also
> triple the number of lines I'd need in the instance initializing portion of
> the program. I may be wrong, but I feel like I should be able to do this
> from a loop. If you have any insight into my problem, I'd greatly appreciate
> it.
>
> Steve

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


Re: [Tutor] How to replace instances

2008-09-26 Thread Richard Lovely
Hi, I'm not going to guess at why this doesn't work, but I've got a
potential solution for you:

class Z(object):
def __init__(self,y):
self.y = y
def replaceZ (self,withWhat):
self.__dict__ = withWhat.__dict__

Is there a reason you can't use a simple assignment (x=y) outside of the class?

On 9/25/08, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> Date: Thu, 25 Sep 2008 04:24:31 -0400
> From: "Steve Collins" <[EMAIL PROTECTED]>
> Subject: [Tutor] How to replace instances
> To: tutor@python.org
> Message-ID:
><[EMAIL PROTECTED]>
> Content-Type: text/plain; charset="iso-8859-1"
>
> I've written a save/load function for a simple program using cPickle. Upon
> saving, a master list, to which all instances are added in their __init__,
> is pickled. when the program starts, if the user wishes to load, a variable
> "load" is set to one, and the pickled list is loaded. All the classes either
> A) initialize using the arguments provided or B) using the the attributes of
> the instances in the un-pickled list. This seems a little clunky to me, but
> it basically works.
> However, some of the instances refer explicitly to other instances
> instances. It's obvious why this causes problems. It occurred to me to
> simply replace the instances with the ones in the un-pickled list, but I
> don't know how.
>
> I tried using the following approach:
>
> class Z:
>def __init__(self,y):
>self.y = y
>def replaceZ (self,withWhat):
>self = withWhat
>
>
> That doesn't raise any errors, but it also doesn't work:
>
> >>> a = X(10)
> >>> b = X(20)
> >>> print a.y
> 10
> >>> print b.y
> 20
> >>> b.replaceZ(a)
> >>> print b.y
> 20
> >>> a
> <__main__.X instance at 0x00D4AE18>
> >>> b
> <__main__.X instance at 0x00D54328>
> >>>
>
> Can anyone tell me how to achieve this?
> -- next part --
> An HTML attachment was scrubbed...
> URL: 
> 
>

-- 
Richard "Roadie Rich" Lovely, part of the JNP|UK Famile
www.theJNP.com
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How to replace instances

2008-09-25 Thread Kent Johnson
On Thu, Sep 25, 2008 at 8:03 AM, Steve Collins <[EMAIL PROTECTED]> wrote:

> that's what I was trying (incorrectly) to achieve the above example.
> but how can I do this for an arbitrary number of objects in a list?
>
> I have a list x = [a,b,c] and a list y = [d,e,f], both filled with
> instance objects.

Note that lists don't contain objects, they contain references to objects.

> I want the instance at x[n] to reference the
> instance at y[n]

This doesn't really make sense, if x[n] and y[n] are the same type of
object. You can have x[n] and y[n] reference the same object, or you
can have them reference different objects with the same value.

> n = 0
> while n < range(len(x))
> x[n] = y[n]
> n+=1

That seems to do what you want. After this loop, x[n] and y[n] will
refer to the same object. How is it not?

I think you still misunderstand what objects and lists and references
are, and this misunderstanding is making it hard to for me to
understand what you are really trying to accomplish. Perhaps you can
give a slightly longer example with real classes and lists, perhaps
one that doesn't do what you want, and we can correct it.

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


Re: [Tutor] How to replace instances

2008-09-25 Thread Steve Collins
On 9/25/08, Kent Johnson <[EMAIL PROTECTED]> wrote:
> On Thu, Sep 25, 2008 at 4:24 AM, Steve Collins <[EMAIL PROTECTED]>
> wrote:
>
>> However, some of the instances refer explicitly to other instances
>> instances. It's obvious why this causes problems. It occurred to me to
>> simply replace the instances with the ones in the un-pickled list, but I
>> don't know how.
>
>> I tried using the following approach:
>>
>> class Z:
>> def __init__(self,y):
>> self.y = y
>> def replaceZ (self,withWhat):
>> self = withWhat
>
> 'self' is just another parameter passed to the method, so this just
> rebinds a local name.
>

That makes sense. At least I understand why it doesn't work now.

> This example doesn't seem to illustrate the situation you describe.
> You can replace the 'y' attribute of a Z object by assigning to it.
>
> One solution might be to make all your objects pickleable. Pickle
> tracks object references and handles embedded references correctly.
>
>> That doesn't raise any errors, but it also doesn't work:
>>
> a = X(10)
> b = X(20)
>
> Presumably this should be Z(10), Z(20) ?
> print a.y
>> 10
> print b.y
>> 20
> b.replaceZ(a)
> print b.y
>> 20
>
> If you want 'b' to refer to the same thing as 'a', just assign
> b = a

that's what I was trying (incorrectly) to achieve the above example.
but how can I do this for an arbitrary number of objects in a list?

I have a list x = [a,b,c] and a list y = [d,e,f], both filled with
instance objects. I want the instance at x[n] to reference the
instance at y[n]

n = 0
while n < range(len(x))
x[n] = y[n]
n+=1

given the contents of your link, I understand why x == [d,e,f] and not
a == d etc., but how can I make a == d by iterating through two lists?

>
> I think you have some common misconceptions about the nature of
> variables and assignment in Python. This may help:
> http://personalpages.tds.net/~kent37/kk/00012.html
>
> Kent
>
I should note that I am very much a novice programmer, and really
appreciate the feedback.

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


Re: [Tutor] How to replace instances

2008-09-25 Thread Kent Johnson
On Thu, Sep 25, 2008 at 4:24 AM, Steve Collins <[EMAIL PROTECTED]> wrote:

> However, some of the instances refer explicitly to other instances
> instances. It's obvious why this causes problems. It occurred to me to
> simply replace the instances with the ones in the un-pickled list, but I
> don't know how.

> I tried using the following approach:
>
> class Z:
> def __init__(self,y):
> self.y = y
> def replaceZ (self,withWhat):
> self = withWhat

'self' is just another parameter passed to the method, so this just
rebinds a local name.

This example doesn't seem to illustrate the situation you describe.
You can replace the 'y' attribute of a Z object by assigning to it.

One solution might be to make all your objects pickleable. Pickle
tracks object references and handles embedded references correctly.

> That doesn't raise any errors, but it also doesn't work:
>
 a = X(10)
 b = X(20)

Presumably this should be Z(10), Z(20) ?
 print a.y
> 10
 print b.y
> 20
 b.replaceZ(a)
 print b.y
> 20

If you want 'b' to refer to the same thing as 'a', just assign
b = a

I think you have some common misconceptions about the nature of
variables and assignment in Python. This may help:
http://personalpages.tds.net/~kent37/kk/00012.html

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