Re: [Tutor] Learning about callbaks
Greetings, my master. I think you need to strip back and simplify, it looks like you may have been reading too many different resources and incorporated some ideas without really understanding what they do and why. I'm humbled by your insight. This is absolutely true. I did some research, reading and test last night and I finally got it working. There was a missing bit that I needed to understand, and suddenly I saw the light. :-) In a manner of speaking. I wrote this piece of code: class UserInput: def __init__(self): pass def test_callback(self, this_callback): print testing the callback this_callback class Game: def __init__(self): self.ui = UserInput() def hello(self): print hello world def useUI(self): self.ui.test_callback(self.hello()) g = Game() g.useUI() I wanted to understand how a parent object could send a callback to a child object, and now I got it. Feel free to comment on this, please. Thank you for your patience, Alan. -- Med venlig hilsen/Kind regards Michael B. Arp Sørensen Programmør / BOFH I am /root and if you see me laughing you better have a backup. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Learning about callbaks
Michael Bernhard Arp Sørensen [EMAIL PROTECTED] wrote I did some research, reading and test last night and I finally got it working. Sorry, but you didn't! However you are very nearly there... class UserInput: def __init__(self): pass def test_callback(self, this_callback): print testing the callback this_callback To actually use the callback you need to use parens: this_callback() But this won't work because of the problem below... class Game: def __init__(self): self.ui = UserInput() def hello(self): print hello world def useUI(self): self.ui.test_callback(self.hello()) Here you do not pass the function object to your test_callback function, you actually call it here! You bneed to pass the function as an object then call it in the receiver self.ui.test_callback(self, self.hello) # no parens means treat as object What you have done is executed the function(which prints the message thus leading you to think it has worked) and passes the return vaklue(None) to your test_callback. But since you never actually call the function there (missing parens) there is no error message. You can prove this by inserting a raw_input statement into your test_callback before you use the callback. That way the message should only appear after you hit return... I wanted to understand how a parent object could send a callback to a child object, and now I got it. Nearly. You apply the parens when you want to execute the function you omit parens when you want to treat the function as an object. You need to swap your use of parens. HTH, -- Alan Gauld Author of the Learn to Program web site http://www.freenetpages.co.uk/hp/alan.gauld ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Learning about callbaks
Hi again. On Jan 2, 2008 2:25 PM, Alan Gauld [EMAIL PROTECTED] wrote: I did some research, reading and test last night and I finally got it working. Sorry, but you didn't! However you are very nearly there... Darn. :-( I've read what to wrote about the *parentheses*. I see why I was wrong in my premature assumption. but I fail to understand why it did work. Anyway, I removed the parentheses from the game method and added it in the userinput method. It still works. Do I dare say that I'm there now? :-) Thanks a lot for this test of my humility and for your effort. -- Med venlig hilsen/Kind regards Michael B. Arp Sørensen Programmør / BOFH I am /root and if you see me laughing you better have a backup. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Learning about callbaks
Michael Bernhard Arp Sørensen [EMAIL PROTECTED] wrote I've read what to wrote about the *parentheses*. I see why I was wrong in my premature assumption. but I fail to understand why it did work. I suspect that if you look closely you'll find that the testing print statement came after the hello world rather than before it. def test_callback(self, this_callback): print testing the callback this_callback Anyway, I removed the parentheses from the game method and added it in the userinput method. It still works. Do I dare say that I'm there now? :-) I hope so, and it should now display the testing message before the hello message. As to whether you are there yet that really depends on whether you are comfortable that you understand the concept clearly. Can you modify the program *without modifying the classes* to use an ordinary function as the callback? Say this goodbye function: def goodbye(): print goodbye world This should not require more than 5 lines of new code and no changes to the existing code. It could be done in 3... If you succeed then I'll be happy that you've grasped it. Alan G. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Learning about callbaks
Hi. On Jan 2, 2008 6:36 PM, Alan Gauld [EMAIL PROTECTED] wrote: Can you modify the program *without modifying the classes* to use an ordinary function as the callback? Say this goodbye function: def goodbye(): print goodbye world This should not require more than 5 lines of new code and no changes to the existing code. It could be done in 3... Like this?: class UserInput: def __init__(self): pass def test_callback(self, this_callback): print testing the callback this_callback() class Game: def __init__(self): self.ui = UserInput() def hello(self): print hello world def useUI(self): self.ui.test_callback(self.hello) def goodbye(): print goodbye world g = Game() g.useUI() g.ui.test_callback(goodbye) It took me a couple of minutes to understand your challenge. :-) Then I remembered that ui is instantiated inside g and therefore callable with the right parameter. Thank you very, very much. I enjoy a good challenge. -- Med venlig hilsen/Kind regards Michael B. Arp Sørensen Programmør / BOFH I am /root and if you see me laughing you better have a backup. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Learning about callbaks
Yes, exactly like that. Well done, you are now callback aware :-) Alan G. - Original Message From: Michael Bernhard Arp Sørensen [EMAIL PROTECTED] To: Alan Gauld [EMAIL PROTECTED] Cc: tutor@python.org Sent: Wednesday, 2 January, 2008 8:19:23 PM Subject: Re: [Tutor] Learning about callbaks Hi. On Jan 2, 2008 6:36 PM, Alan Gauld [EMAIL PROTECTED] wrote: Can you modify the program *without modifying the classes* to use an ordinary function as the callback? Say this goodbye function: def goodbye(): print goodbye world This should not require more than 5 lines of new code and no changes to the existing code. It could be done in 3... Like this?: class UserInput: def __init__(self): pass def test_callback(self, this_callback): print testing the callback this_callback() class Game: def __init__(self): self.ui = UserInput() def hello(self): print hello world def useUI(self): self.ui.test_callback(self.hello) def goodbye(): print goodbye world g = Game() g.useUI() g.ui.test_callback(goodbye) It took me a couple of minutes to understand your challenge. :-) Then I remembered that ui is instantiated inside g and therefore callable with the right parameter. Thank you very, very much. I enjoy a good challenge. -- Med venlig hilsen/Kind regards Michael B. Arp Sørensen Programmør / BOFH I am /root and if you see me laughing you better have a backup. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Learning about callbaks
Greetings, my masters. This is somewhat difficult to transfer to my program with 2 classes/objects. All examples I've seen is not for more than one instance of a single object. I use more than one class in my program. I have a game class and a menu class. When the user chooses quit in the menu, I want the menu object to call a method that executes a quit_program() from the game class. Obviously, menu is an object within the game object. class UserInput(CommonBase): def __init__(self, queue, game): self.loop = 1 self.queue = queue self.game = game def main(self): while True: tstr = raw_input(Input string: ) print Input: , tstr if tstr == q: self.quitProgram() def quitProgram(self, game, quit_callback): self.loop = 0 game.loop = 0 quit_callback() class Game(CommonBase): def __init__(self): self.loop = 1 self.queue = Queue.Queue() def startUI(self, tid): ui = UserInput(self.queue, self) ui.main() def stoploop(): self.loop = 0 def main(self): thread.start_new_thread(self.startUI, (1,)) while self.loop: try: data = self.queue.get(block = False) except Queue.Empty: pass else: pass time.sleep(0.1) g = Game() g.main() It is so frustrating not to see the light. I feel that I'm close to understanding the general idea. Allthough I might be wrong on that point. :-) I'm desperate. Thanks in advance. On Dec 29, 2007 7:58 PM, Dave Kuhlman [EMAIL PROTECTED] wrote: Here is a trivial example: def f1(x): print 'f1: %s' % x def f2(x): print 'f2: %s' % x def use_them(funcs): for func in funcs: func('abcd') def test(): funcs = [f1, f2] use_them(funcs) test() -- Med venlig hilsen/Kind regards Michael B. Arp Sørensen Programmør / BOFH I am /root and if you see me laughing you better have a backup. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Learning about callbaks
Michael Bernhard Arp Sørensen [EMAIL PROTECTED] wrote I have a game class and a menu class. When the user chooses quit in the menu, I want the menu object to call a method that executes a quit_program() from the game class. self.game.quit_program() should do it. Except in your code bekow you don't define a quit_program method in the Game class. Obviously, menu is an object within the game object. Not obviously, but it's certainly an option. You could have kept menu as a separate object if that made more sense to you. But having a menu contained by Game is also fine. - class UserInput(CommonBase): def __init__(self, queue, game): self.loop = 1 self.queue = queue self.game = game def main(self): while True: tstr = raw_input(Input string: ) print Input: , tstr if tstr == q: self.quitProgram() def quitProgram(self, game, quit_callback): self.loop = 0 game.loop = 0 quit_callback() --- I'm not sure I really understand what this class is modelling. What kind of an object is UserInput? Does it represent a single command or is it representing an action - getting input from the user? In which case its a very abstract kind of object. If this (as I think) is the menu that you refer to above then I'd expect it to be responsible for displaying a menu and obtaing a selection, it could then dispatch a message to the associated operatrion (a callback). However this class has a queue and game parameter that are assigned to local attribiutes but then never used... The main() method displays the prompt and then calls the quit method with no arguments. The quit method tries to use a call back function but the call back is never passed to it. In fact in this case you don't even need a callback since the UserInput object has an attribute pointing at the game object so you can call game methods directly. I'm also not sure what the threading stuff is needed for either. Try to simplify the example by cutting out all the redundant stuff and not using callbacks initially, just call the game methods via the game attribute. Then once it works modify it to use callback style. Also, in the code below you are using loop as a boolean so it would be better to assign True/False rather than 1/0 as values. class Game(CommonBase): def __init__(self): self.loop = 1 self.queue = Queue.Queue() def startUI(self, tid): ui = UserInput(self.queue, self) ui.main() def stoploop(): self.loop = 0 def main(self): thread.start_new_thread(self.startUI, (1,)) while self.loop: try: data = self.queue.get(block = False) except Queue.Empty: pass else: pass time.sleep(0.1) g = Game() g.main() Allthough I might be wrong on that point. I'm desperate. I think you need to strip back and simplify, it looks like you may have been reading too many different resources and incorporated some ieas without really undertansding what they do and why. HTH, -- Alan Gauld Author of the Learn to Program web site http://www.freenetpages.co.uk/hp/alan.gauld ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Learning about callbaks
Michael Bernhard Arp Sørensen [EMAIL PROTECTED] wrote Greetings, my master. Nah, there are no masters on the tutor list, we are all learning together, just at different stages. If you really want the masters go to comp.lang.python! :-) I'm writing a game based on curses. OK, That gives us a much better context from which to work. My imidiate problem is when I select Quit from the menu, I need to send the string back to the caller/parent class for evaluation. For a good quick tutorial on programming menus in curses try David Metz' article from his excellent Charming Python series - a resouerce every Python programmer should read IMHO... http://www.ibm.com/developerworks/linux/library/l-python6.html Off topic: I must say that I'm amazed by this tutor thing. Yes, the Python tutor list is one of the best features of Python. I hope I can repay the python community some day when I'm smart enough. :-) Just keep reading and when you one day see a question you can answer jump in! Participation is the life blood of Open Source software at every level. Enjoy, Alan G. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Learning about callbaks
On Sun, Dec 30, 2007 at 09:17:42AM -, Alan Gauld wrote: Yes, the Python tutor list is one of the best features of Python. This expresses exactly the way I feel about python. Everytime I have to work in another language, I keep asking myself: but where is the tutor mailing list for this language? Tiago. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Learning about callbaks
Hi there. I want to learn about callbacks because we use it at work in our software. I there a short hello world-like version of a callback example? -- Med venlig hilsen/Kind regards Michael B. Arp Sørensen Programmør / BOFH I am /root and if you see me laughing you better have a backup. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Learning about callbaks
Greetings, my master. I'm writing a game based on curses. I have my own screen object and several child objects to handle sub windows with e.g. menues, board/map/views and log outputs. All user input is done with screen.getch and later sent to the dynamic menu for selecting menu points. My imidiate problem is when I select Quit from the menu, I need to send the string back to the caller/parent class for evaluation. Later I will need to design all the menues and the related methods, other sub windows in different threads for individual updates. But first I need a working UI. Off topic: I must say that I'm amazed by this tutor thing. To really have my own tutor in this new programming language I'm learning, is kinda blowing my mind. I hope I can repay the python community some day when I'm smart enough. :-) Thanks in advance /karneevor On Dec 29, 2007 6:39 PM, Alan Gauld [EMAIL PROTECTED] wrote: Michael Bernhard Arp Sørensen [EMAIL PROTECTED] wrote I want to learn about callbacks because we use it at work in our software. Can you be more specific about what you want to know. Callbacks are used in many different ways from event handling methods in a GUI to network programming to simulating synchronous protocols over an asynchronous connection. I there a short hello world-like version of a callback example? See almost any GUI tutorial. The recent thread Closing GUI program had the following example from Michael Goldwasser #--- from Tkinter import Tk,Label def onClose(): root.destroy() # stops the main loop and interpreter root = Tk() root.protocol(WM_DELETE_WINDOW, onClose) # handle event when window is closed by user z = Label(root, text=Hello World!) z.grid() root.mainloop() #--- In this example the onClose() event handler is a callback function. The folowing pseusdo code shows how the principle can be used for asynchronous network programming: waiting = {} # list of objects awaiting responses id = 0 def sendToServer(msg, callback) msgSent = prepareMessage(msg) id = server.send(msgSent) waiting[id] = (msg, callback) def func1() msg = prepareData() sendToServer(msg, func1_cont) def func1_cont(original, result) x,y,z = result.getValues() processData(x,y,z,original.p,original.q) while server.listen() msg = server.recv() id = msg.getID() oldMessage = waiting[id][0] callback = waiting[id][1] callback(oldmessage, msg) del(waiting[id]) In this example we can think of the main application calling func. func1 needs to send a message to a server and process the response but the server has an asynchronous protocol so we split the function into func1 and func1_cont at the point of calling the server. Then when the server send us the response we pull the stored state out of the dictionary and combine it with the server data to complete the func1 processing via the func1_cont callback. In practice we'd probably store the date/time with the transaction data so that we can check for timeouts etc in a separate thread... The important thing with all callbacks is that you match up the data expected by the callback with the data actually available at the point of calling it. In this case we take the architectural decision to pass callback functions the old and new data structures. We could alternatively have passed the transaction id and let the callback retrieve (and delete) the data from the waiting list. I hope that all makes sense. -- Alan Gauld Author of the Learn to Program web site http://www.freenetpages.co.uk/hp/alan.gauld ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor -- Med venlig hilsen/Kind regards Michael B. Arp Sørensen Programmør / BOFH I am /root and if you see me laughing you better have a backup. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor