Re: self-aware list of objects able to sense constituent member alterations?
On Jan 28, 4:37 am, John O'Hagan wrote: > On Tue, 27 Jan 2009, Reckoner wrote: > > I'm not sure this is possible, but I would like to have > > a list of objects > > > A=[a,b,c,d,...,z] > > > where, in the midst of a lot of processing I might do something like, > > > A[0].do_something_which_changes_the_properties() > > > which alter the properties of the object 'a'. > > > The trick is that I would like A to be mysteriously aware that > > something about the object 'a' has changed so that when I revisit A, > > I will know that the other items in the list need to be refreshed to > > reflect the changes in A as a result of changing 'a'. > > > Even better would be to automatically percolate the subsequent changes > > that resulted from altering 'a' for the rest of the items in the list. > > [...] > > Interesting question. > > Maybe this is too simple for your purpose (or maybe just wrong!), but could > you subclass list and give it an "update" method which keeps a dictionary of > the state of its members and/or calls another method that makes the > appropriate changes in the other members when a change occurs, something > like: > > class SelfAwareList(list): > > state_dict = {} > > def update(self): > for i in self: > if i.state == 'some_condition': > self.do_stuff_to_other_members() > self.state_dict[i] = i.state > > def do_stuff_to_other_members(self): > print 'doing stuff...' > > ? > > You could manually call update() on the SelfAwareList instance after calling a > method on a SelfAwareList member, or even build it into the members' methods > so that it was automatic. > > HTH, > > John Hi Reckoner & John O'Hagan, Great thread, very interesting. John, I haven't seen anything like your class that uses list instead of object and refers to state directly (i.state in self). Could you elaborate? Here would be my implementation of your idea: class SelfAwareList2(object): def __init__(self, l): self.l = l self.changed = [False for element in l] def __str__(self): return str(self.l) def update(self, index, value): self.l[index] = value self.changed[index] = True def do_stuff_to_other_members(self): for i in self.changed: if i==False: self.l[i] += 1 Here you can print and whenever you update your list, self.changed keeps track of what changed. Later on you can call do_stuff_to_others which in this case adds 1 to each other element. I assume that your class replaces the awkwardness of l.update(0, 5) with l[0] = 5, but I can't quite wrap my mind around it. Luther. -- http://mail.python.org/mailman/listinfo/python-list
socket send help
Hi everyone, New guy here. I'm trying to figure out sockets in order to one day do a multiplayer game. Here's my problem: even the simplest examples don't work on my computer: A simple server: from socket import * myHost = '' myPort = 21500 s = socket(AF_INET, SOCK_STREAM)# create a TCP socket s.bind((myHost, myPort))# bind it to the server port s.listen(5) # allow 5 simultaneous connections while True: connection, address = s.accept() while True: data = connection.recv(1024) if data: connection.send('echo -> ' + data) else: break connection.close() # close socket And a simple client: import sys from socket import * serverHost = 'localhost'# servername is localhost serverPort = 21500 # use arbitrary port > 1024 s = socket(AF_INET, SOCK_STREAM)# create a TCP socket s.connect((serverHost, serverPort)) # connect to server on the port s.send('Hello world') # send the data data = s.recv(1024) # receive up to 1K bytes print(data) If I run testserver.py via the cmd prompt in Windows XP and then the testclient.py program, I get the following error: Traceback (most recent call last): File "C:\Python30\testclient.py", line 12, in s.send('Hello world') # send the data TypeError: send() argument 1 must be string or buffer, not str This happens in 2.6 or 3.0 and with different example client & server programs from the web. What am I missing? Thanks, John R. -- http://mail.python.org/mailman/listinfo/python-list
Re: socket send help
Chris & Gabriel, Thank you so much. My simple example now works. It was very frustrating that even the simple example didn't work, so your help is most appreciated. b'hello world' was the key. As for the error, I do still get it with 3.0 final so I'll go ahead and report it. John. On Dec 24, 12:03 am, "Gabriel Genellina" wrote: > En Wed, 24 Dec 2008 03:59:42 -0200, greyw...@gmail.com > escribió: > > > New guy here. I'm trying to figure out sockets in order to one day do > > a multiplayer game. Here's my problem: even the simplest examples > > don't work on my computer: > > > A simple server: > > > fromsocketimport * > > myHost = '' > > Try with myHost = '127.0.0.1' instead - a firewall might be blocking your > server. > > > s.listen(5) # allow 5 simultaneous connections > > Not exactly: your server program only handles a single connection at a > time. The 5 above specifies how many connections may exist "on hold" > waiting for you to accept() them. > > > connection.send('echo -> ' + data) > > That's fine for Python 2.6, but you must use b'echo -> ' with 3.0 > > > And a simple client: > > > s.send('Hello world') # send the data > > Same as above, should be b'Hello world' with Python 3.0 > > > If I run testserver.py via the cmd prompt in Windows XP and then the > > testclient.py program, I get the following error: > > > Traceback (most recent call last): > > File "C:\Python30\testclient.py", line 12, in > > s.send('Hello world') # send the data > > TypeError: send() argument 1 must be string or buffer, not str > > The above error message is wrong (and I think it was corrected on the 3.0 > final release; if you got it with 3.0 final, file a bug report at > http://bugs.python.org/) > > > This happens in 2.6 or 3.0 and with different example client & server > > programs from the web. What am I missing? > > The error above surely comes from 3.0; with 2.6 you should get a different > error (if it fails at all). Try again with 2.6.1. I didn't run the code > but it looks fine -- if you got it from a book or article, unless it > explicitely says "Python 3.0", assume it was written for the 2.x series. > > -- > Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list
Re: socket send help
Hi again, I've done some more playing around with socket and socketserver and have discovered I can send strings or lists with socket.send() by converting to bytes. But lists with strings in them or dicts can't be converted by bytes(). How can I send those? One idea I initially tried was to set up a server (host,port) for receiving data and another one (host, different port) for strings, but that didn't work so I was thinking of throwing everything into a list or a dictionary and sending that but that's not working either. Any ideas? Thanks, John. On Dec 24, 12:03 am, "Gabriel Genellina" wrote: > En Wed, 24 Dec 2008 03:59:42 -0200, greyw...@gmail.com > escribió: > > > New guy here. I'm trying to figure out sockets in order to one day do > > a multiplayer game. Here's my problem: even the simplest examples > > don't work on my computer: > > > A simple server: > > > fromsocketimport * > > myHost = '' > > Try with myHost = '127.0.0.1' instead - a firewall might be blocking your > server. > > > s.listen(5) # allow 5 simultaneous connections > > Not exactly: your server program only handles a single connection at a > time. The 5 above specifies how many connections may exist "on hold" > waiting for you to accept() them. > > > connection.send('echo -> ' + data) > > That's fine for Python 2.6, but you must use b'echo -> ' with 3.0 > > > And a simple client: > > > s.send('Hello world') # send the data > > Same as above, should be b'Hello world' with Python 3.0 > > > If I run testserver.py via the cmd prompt in Windows XP and then the > > testclient.py program, I get the following error: > > > Traceback (most recent call last): > > File "C:\Python30\testclient.py", line 12, in > > s.send('Hello world') # send the data > > TypeError: send() argument 1 must be string or buffer, not str > > The above error message is wrong (and I think it was corrected on the 3.0 > final release; if you got it with 3.0 final, file a bug report at > http://bugs.python.org/) > > > This happens in 2.6 or 3.0 and with different example client & server > > programs from the web. What am I missing? > > The error above surely comes from 3.0; with 2.6 you should get a different > error (if it fails at all). Try again with 2.6.1. I didn't run the code > but it looks fine -- if you got it from a book or article, unless it > explicitely says "Python 3.0", assume it was written for the 2.x series. > > -- > Gabriel Genellina -- http://mail.python.org/mailman/listinfo/python-list
simple turn-based multiplayer game via TCP server/client
Hi everyone, I'm learning python to get a multiplayer roleplaying game up and running. I didn't see any simple examples of multiplayer games on the web so I thought I'd post mine here. I choose Rock, Paper, Scissors as a first game to experiment with as the game logic/options are easy to implement and understand. Initially, I tried to get the socketserver.TCPServer example in the Python Docs to work, but couldn't get my game variables into the handle method of the class MyTCPHandler. And I didn't know how else to do it. I ended up creating my own server & client out of simple sockets based on the simple echo server & client examples in the Python Docs. I also wanted to send chat messages OR game variables back & forth, but I couldn't figure out how to do the OR, so the basic idea in this implementation is to send the dictionary 'game' back and forth. game dict contains all the gaming variables as well as any chat messages. The program processes results depending on whether the game is starting, there's a chat message, or there's a game move. Finally, in testing, I ran the server in IDLE, but I had to load a command prompt and switch to c:\python30; then type 'python rpsmulti.py' for the client every time. Anyone know how to test server/client code strictly in IDLE? Anyway, try it out and let me know how you would improve it. John R. # NAME: rpsmulti.py # DESCRIPTION: rock, paper, scissors game multiplayer game # AUTHOR: John Robinson # DATE: 1/3/09 # VERSION: Python 3.0 # TO DO: # .server_address instead of HOST, PORT? import socket from random import choice from pickle import dumps, loads from pprint import pprint HOST, PORT = "localhost", # defined for now BUFFSIZE = 1024 # for socket.send & recv commands BACKLOG = 2 # number of clients supported by server SECONDS = 3 # seconds until socket.timeout (not implemented) # moves dict to translate 'rps' choice MOVES = {'r':'Rock', 'p':'Paper', 's':'Scissors'} # outcome dict stores result for all possible scenarios OUTCOME = {('p','r'): 'win', ('r','s'): 'win', ('s','p'): 'win', ('p','p'): 'draw', ('r','r'): 'draw', ('s','s'): 'draw', ('r','p'): 'lose', ('s','r'): 'lose', ('p','s'): 'lose'} def main_menu(game): """ initialize game dict variables & opening screen of the game """ game['total'] = 0 # total number of games played game['won'] = 0 # total games won by player game['lost'] = 0# total games lost by player game['drew'] = 0# total games drew by player game['move'] = '' # player's move (rps) game['message'] = ''# player's chat message game['sentmessage'] = ''# player's previous message game['start'] = True# setting up the game boolean print("\tROCK PAPER SCISSORS\n") if game['name']=='':# if returning to menu don't display the following game['name'] = get_name() print("Welcome "+game['name']+". Remember...") print("Rock smashes scissors! Paper covers Rock! Scissors cuts paper!\n") print("1. Play single player game") print("2. Start two player game") print("3. Join two player game") print("4. Quit") print() c = safe_input("Your choice? ", "1234") c = int(c) if c==1: one_player(game) elif c==2: start_two_player(game) elif c==3: two_player_join(game) else: print('Play again soon.') def safe_input(prompt, values='abcdefghijklmnopqrstuvwxyz'): """ gives prompt, checks first char of input, assures it meets given values default is anything goes """ while True: i = input(prompt) try: c = i[0].lower() except IndexError: # the only possible error?! if c=='': print("Try again.") else: if c not in values: # some other character print("Try again.") else: # looks good. continue. break return i def get_name(): """ returns input as name """ while True: name = input("What is your name? ") check = input(name + ". Correct (y/n)? ") if check[0] in 'yY': break return name def get_result(player, opponent): """ reports opponent's choice; checks player and opponent dicts ['move'] against OUTCOME dict; reports result returns player dict with updated values """ print(opponent['name'], 'chose %s.' % (MOVES[opponent['move']])) # check lookout dict (OUTCOME dictionary) result = OUTCOME[(player['move'], opponent['move'])] # update game variables player['total'] += 1 if result=='win': print('%s beats %s. You win.' % (MOVES[player['move']], MOVES [opponent['move']])) player['won'] += 1 elif result=='draw':
passing a tuple into a class function as a single argument
Hi everyone, The following program doesn't work as expected: #Python 2.7 & wxPython 2.9 import wx class MyFrame(wx.Frame): """ We simply derive a new class of Frame. """ def __init__(self, parent, title): wx.Frame.__init__(self, parent, title=title, size=(200,100)) self.control = wx.TextCtrl(self, style=wx.TE_MULTILINE) self.Show(True) app = wx.App(False) size=(600,400) frame = MyFrame(None, 'Small editor') #frame = MyFrame(None, 'Small editor', (600,400)) app.MainLoop() If I use the default size=(200,100) it's just fine. But if I try it pass it a new size (600,400), I get the following error: Traceback (most recent call last): File "C:\Python27\wxpythoneasy1.py", line 13, in frame = MyFrame(None, 'Small editor',((600,400))) TypeError: __init__() takes exactly 3 arguments (4 given) It seems like it's begging to have it pass a different size than the default, but there doesn't seem to be a way to pass a tuple as a single argument. Any help would be appreciate. Thanks, John R. -- http://mail.python.org/mailman/listinfo/python-list