Re: [Tutor] passing global variable as argument.
On 07/16/2012 07:00 AM, Bala subramanian wrote: Friends, I want to define a function that can populate an array by taking its name (which is defined globally). I defined two empty arrays as follows and a function that can populate the array. REF_F1=np.array([]) REF_F2=np.array([]) # populating the given array def ref(ln,REF_F1): global REF_F1 REF_F1=np.zeros((ln,3),dtype='float32') for i in range(ln): for j in range(3): REF_F1x[i,j]=resid[Index[i]].cent()[j] ref(ln, REF_F2) In this case, when i pass REF_F2 as argument, the fn. always populates array REF_F1. I also tried something like the following *def ref(ln,x=REF_F1)* and then calling as *ref(ln,x=REF_F2)*. The result is the same. Could someone please give me hint on how pass global variables as arguments. Thanks, Bala When you use a non-standard library, you really ought to mention what it is. I'm assuming np refers to numpy, which i'm not familiar with. So I won't address any particular quirks of that library. When you use the global statement in a function, you are saying you want a particular global value, so the argument detail is irrelevant. Seems to me it should have been a compile error. Nix the global statement if you really want to pass it as an argument. And for readability, call the formal parameter something else, and do not capitalize it. it's not read-only; you're intending to change it. Since I don't know numpy, I'll have to use a built-in type for example. I choose list. (untested) myglobal1 = [3,4] myglobal2 = [5,6,7] def myfunc(ln, target): while target: target.pop() for i in xrange ln: target.append(3*i) for j in xrange(ln): target[j] += 5 myfunc(10, myglobal1) myfunc(5, myglobal2) A key point is I do not bind my local variable target to a new object. If I do, I'll have no effect on the global object. So I cannot use the following line: target = [] I also notice you use 'ref' several places. Perhaps you're under the mistaken belief that Python does references. -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] passing global variable as argument.
On Mon, 16 Jul 2012, Bala subramanian wrote: Friends, I want to define a function that can populate an array by taking its name (which is defined globally). Are you sure this is what you really want to do? I've noticed that many times that I want to do something, but only because I don't understand how to do it a better way. I defined two empty arrays as follows and a function that can populate the array. REF_F1=np.array([]) REF_F2=np.array([]) # populating the given array def ref(ln,REF_F1): global REF_F1 My command of the global syntax is a little weak, but I'm going to say what is probably happening with this line is that you are telling python you now want to refer to the REF_F1 that lives in the global namespace, not the one that was passed in to your function. REF_F1=np.zeros((ln,3),dtype='float32') This line here tells me that what I mentioned first is correct. You don't care *what* the array is before hand, because you're actually zeroing the array. Read the conclusion below. for i in range(ln): for j in range(3): REF_F1x[i,j]=resid[Index[i]].cent()[j] I'm not sure what `resid` or `Index` are. Also, REF_F1x wasn't defined anywhere so you're probably getting a name error here. When sending code, especially misbehaving code, the best thing to do is provide a SMALL, but complete program that can be run on its own, as long as one has the dependencies. ref(ln, REF_F2) In this case, when i pass REF_F2 as argument, the fn. always populates array REF_F1. I also tried something like the following *def ref(ln,x=REF_F1)* and then calling as *ref(ln,x=REF_F2)*. The result is the same. Could someone please give me hint on how pass global variables as arguments. First off, the whole point of global variables are so that you don't have to pass them as arguments. This is fine, and there are occasions where you legitimately want to have a global variable - but this isn't one of them. When you use globals improperly, they cause maintenance nightmares by making it really hard to figure out what's going on in your code. At least Python requires you to explicitly state that you care about some global value with the global keyword. But in this case it looks like you don't actually care about the original array - you're completely replacing the values based on whatever the value of `ln` is. So instead you could do something like def initialize_array(ln): new_array = np.zeros((ln,3),dtype='float32') for i in range(ln): for j in range(3): new_array[i,j]=resid[Index[i]].cent()[j] return new_array And then you would call it like this: REF_F2 = ref(ln) HTH, Wayne ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] passing global variable as argument.
Bala subramanian wrote: Friends, I want to define a function that can populate an array by taking its name (which is defined globally). I defined two empty arrays as follows and a function that can populate the array. In general it is tricky to resize and populate numpy arrays in place. It is usually better to just create a fresh array and reassign it. Something like this should probably work: def ref(length): arr = np.zeros((length, 3), dtype='float32') for i in range(length): for j in range(3): arr[i, j] = resid[Index[i]].cent()[j] return arr ref_f1 = ref(3) ref_f2 = ref(5) should work for you. (I can't test it because you don't say what resid and Index are.) To explain why your earlier code does not work the way you expect, read on: REF_F1=np.array([]) REF_F2=np.array([]) # populating the given array def ref(ln,REF_F1): So far this is good -- your function takes an argument called REF_F1, which can be any array you like. It's just a local name. The function sees REF_F1 is a local variable. global REF_F1 But this is no good, because now you declare the name REF_F1 to be global instead of local. So now the function sees REF_F1 as a global variable, and everything that you do to it, occurs to the global called REF_F1. By the way, this bug is no longer permitted in the latest version of Python. Using Python 3.2: py x = 23 py def func(x): ... global x ... print(x =, x) ... File stdin, line 1 SyntaxError: name 'x' is parameter and global In general, if you feel the need to use global, 90% of the time you are doing something wrong and will have problems. You should avoid using global unless absolutely necessary. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] passing global variable as argument.
Thank you wayne and steven. You suggestion to create a fresh array within the function and assigning it to variable worked fine and the result was exactly what i was looking for. In future i remember not to use global variables as fn. parameters. thanks once again for detailed explanation, bala On Mon, Jul 16, 2012 at 5:06 PM, Steven D'Aprano st...@pearwood.infowrote: Bala subramanian wrote: Friends, I want to define a function that can populate an array by taking its name (which is defined globally). I defined two empty arrays as follows and a function that can populate the array. In general it is tricky to resize and populate numpy arrays in place. It is usually better to just create a fresh array and reassign it. Something like this should probably work: def ref(length): arr = np.zeros((length, 3), dtype='float32') for i in range(length): for j in range(3): arr[i, j] = resid[Index[i]].cent()[j] return arr ref_f1 = ref(3) ref_f2 = ref(5) should work for you. (I can't test it because you don't say what resid and Index are.) To explain why your earlier code does not work the way you expect, read on: REF_F1=np.array([]) REF_F2=np.array([]) # populating the given array def ref(ln,REF_F1): So far this is good -- your function takes an argument called REF_F1, which can be any array you like. It's just a local name. The function sees REF_F1 is a local variable. global REF_F1 But this is no good, because now you declare the name REF_F1 to be global instead of local. So now the function sees REF_F1 as a global variable, and everything that you do to it, occurs to the global called REF_F1. By the way, this bug is no longer permitted in the latest version of Python. Using Python 3.2: py x = 23 py def func(x): ... global x ... print(x =, x) ... File stdin, line 1 SyntaxError: name 'x' is parameter and global In general, if you feel the need to use global, 90% of the time you are doing something wrong and will have problems. You should avoid using global unless absolutely necessary. -- Steven __**_ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/**mailman/listinfo/tutorhttp://mail.python.org/mailman/listinfo/tutor -- C. Balasubramanian ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Passing a Variable
On Mon, Apr 4, 2011 at 7:27 AM, Ryan Strunk ryan.str...@gmail.com wrote: I've read your code. Frankly I don't understand your problem. I also don't see any occurrence of health. There isn't a reference to health here. My goal is to have this code act as a checker for health, fatigue, time_remaining, or any other sort of statistic you'd like to throw into it. My problem is that when I try: instance = Statistic(stat=health, sound=spam, low=1, mid=15, high=30) health can change elsewhere in the program, but the instance of statistic class won't automatically see it. My proposal would be to wrap the stats in an object: Class stat: __init__(self, name, value) self.type = name self.value = value Then in the player object change the initialisation health = startvalue to health = stat(health, startvalue) and change every other reference to health to a reference to health.value. Then you can use the current code if you replace self.stat outside the __init__ by self.stat.value You could even consider merging the stats and Statistics classes. == Another possibility would be to use a getter method and the fact that methods are objects: In the player object add: def get_health(self): return self.health change the call to: instance = Statistic(stat=get_health, sound=spam, low=1, mid=15, high=30) and replace self.stat by self.stat() everywhere in the Statistics code -- André Engels, andreeng...@gmail.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Passing a Variable
On 04/04/11 11:55, Ryan Strunk wrote: Hi list, I am in the midst of trying to code a game based entirely on audio cues, and I've run into a bit of a snag when trying to monitor certain variables. I'll lay out the framework of what I'm going for in the hope that it makes sense when written down. In a standard video game I could have a health bar go from normal to yellow to red as it diminishes. In audio, though, I don't have that luxury. As a result, I have conceptualized a system whereby a player hears a sound every so often if a particular stat drops into the caution range. If the player drops into the danger range, the sound loops continuously. I also wanted to make sure that if the player dropped from caution to danger, there wasn't a big, awkward pause in the sound loop and that the player would know immediately that his stat had dropped (see first and second if checks in the check method). The problem: My existing methods directly update stats. For example: the player class has a self.health stat which is directly affected by other methods. This has caused no problem up until now. When I pass self.health to the code I will paste below, however, the Statistic class does not receive health, but rather health's value. I understand that python passes variables by value and not by reference, and this has not been a problem up until now. Now that I am trying to design a class which explicitly checks a specific variable, though, I can't fathom a way to do it unless I pass a direct reference, and I'm not sure that can be done. I need to figure out a way for the below code to check the value of the health variable and act on it. This way, if player's self.health changes, the static class will take note of that and respond accordingly. It occurred to me to make Statistic a child of int, but I'm told that's more trouble than I probably want to deal with. Any suggestions/advice anyone has would be greatly appreciated. Rather than having Statistic polling the Player's health, I suggest that the Player object should call a method in Statistic class when its health changes, and then the Statistic class can see if the value change is relevant or not (e.g. whether to start playing audio, or not). Since you said that you modified self.health directly, in some other languages this might cause you problems. But behold, this is python, you can easily turn your attribute into property: class Player(object): def __init__(self): self.stat = Statistic() self._health = 100 @property def health(self): return self._health @health.setter def health(self, value): self.stat.health_changed(self, value) self._health = value class Statistic(object): def __init__(...): ... def health_changed(self, player, value): if value player.health: play_once('taking damage') elif value player.health: play_once('getting healed') if value self.low: self.status = 'danger' play_repeat('danger') elif value self.mid: self.status = 'warning' play_repeat('warning') else: self.status = 'safe' play_stop() Best, Ryan import sound_lib from game_utils import delay #this encapsulates threading.Timer's assignment and start method class Statistic(object): def __init__(self, stat=None, sound=None, low=None, mid=None, high=None): self.stat = stat self.sound = sound self.low = low self.mid = mid self.high = high self.status = 'safe' self.auto_check_timer = None def auto_check(self): if self.stat self.high: self.status = 'safe' return if self.mid = self.stat = self.high: self.status = 'caution' self.sound.play(True) self.auto_check_timer = delay(self.sound.bytes_to_seconds(len(self.sound))*2, self.auto_check) return if self.low = self.stat self.mid: self.status = 'danger' self.sound.play(True) self.auto_check_timer = delay(self.sound.bytes_to_seconds(len(self.sound)), self.auto_check) def check(self): if self.status = 'caution' and self.low = self.stat self.mid: #This will set the program to start a constant alarm when the stat level has dropped below caution self.auto_check_timer.cancel() if self.sound.is_playing: #to assist in setting up the caution to danger transition #a standard playing sound will have a timer running alongside it, so skip the next guard and return if self.auto_check_timer.is_alive() == False: #guard to make sure program doesn't catch every playing sound, should prevent repeated checks from recalling auto_check sound_duration =
Re: [Tutor] Passing a Variable
On Sun, Apr 03, 2011 at 08:55:25PM -0500, Ryan Strunk wrote: I understand that python passes variables by value and not by reference You understand wrongly. Python is neither pass-by-value nor pass-by-reference. I've written thousands of words on this topic before, so excuse me if I'm a little terse. Rather than write it all out again, I'll just point you at this post: http://mail.python.org/pipermail/tutor/2010-December/080505.html You might also like to read this: http://effbot.org/zone/call-by-object.htm and this has not been a problem up until now. Now that I am trying to design a class which explicitly checks a specific variable, though, I can't fathom a way to do it unless I pass a direct reference, and I'm not sure that can be done. One standard way to do this is to have your statistic class have a player attribute, and then have it check the player.health attribute. class Statistic(object): # Check statistics of a player. def __init__(self, player): self.player = player def check_health(self): if self.player.health 0: print Bam, you're dead! An alternative is to have the player object check its own health, calling some appropriate notification object. This could be a global variable, or an attribute of the player (that way each player could have their own notification user-interface). notifier = Notify(sound='on', health_bar='off') # whatever... class Player(object): def __init__(self): self.health = 100 def check_health(self): if self.health 0: notifier.announce_dead(self) elif self.health 10: notifer.announce_critical(self) else: notifier.announce_normal(self) Or any of many variations on these. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Passing a Variable
On 4/3/2011 9:55 PM, Ryan Strunk wrote: Hi list, Hi I've read your code. Frankly I don't understand your problem. I also don't see any occurrence of health. Could you point to a specific line of code, explain what you want and what you are getting. Also your description of the program and the program itself is kinda overwhelming, and so much of that information is not relevant to your question. That makes it hard to understand the question. How about posting the smallest possible piece of code that exemplifies the problem? Python does not pass by value. It passes a reference to the argument. In essence: def foo(a): pass b = somePythonObject # b is now a reference to somePythonObject foo(b) In calling the function Python binds local name a to somePythonObject a is now another reference to somePythonObject I am in the midst of trying to code a game based entirely on audio cues, and I've run into a bit of a snag when trying to monitor certain variables. I'll lay out the framework of what I'm going for in the hope that it makes sense when written down. In a standard video game I could have a health bar go from normal to yellow to red as it diminishes. In audio, though, I don't have that luxury. As a result, I have conceptualized a system whereby a player hears a sound every so often if a particular stat drops into the caution range. If the player drops into the danger range, the sound loops continuously. I also wanted to make sure that if the player dropped from caution to danger, there wasn't a big, awkward pause in the sound loop and that the player would know immediately that his stat had dropped (see first and second if checks in the check method). The problem: My existing methods directly update stats. For example: the player class has a self.health stat which is directly affected by other methods. This has caused no problem up until now. When I pass self.health to the code I will paste below, however, the Statistic class does not receive health, but rather health's value. I understand that python passes variables by value and not by reference, and this has not been a problem up until now. Now that I am trying to design a class which explicitly checks a specific variable, though, I can't fathom a way to do it unless I pass a direct reference, and I'm not sure that can be done. I need to figure out a way for the below code to check the value of the health variable and act on it. This way, if player's self.health changes, the static class will take note of that and respond accordingly. It occurred to me to make Statistic a child of int, but I'm told that's more trouble than I probably want to deal with. Any suggestions/advice anyone has would be greatly appreciated. Best, Ryan import sound_lib from game_utils import delay #this encapsulates threading.Timer's assignment and start method class Statistic(object): def __init__(self, stat=None, sound=None, low=None, mid=None, high=None): self.stat = stat self.sound = sound self.low = low self.mid = mid self.high = high self.status = 'safe' self.auto_check_timer = None def auto_check(self): if self.stat self.high: self.status = 'safe' return if self.mid= self.stat= self.high: self.status = 'caution' self.sound.play(True) self.auto_check_timer = delay(self.sound.bytes_to_seconds(len(self.sound))*2, self.auto_check) return if self.low= self.stat self.mid: self.status = 'danger' self.sound.play(True) self.auto_check_timer = delay(self.sound.bytes_to_seconds(len(self.sound)), self.auto_check) You can simplify the above logic: if self.stat self.high: self.status = 'safe' elif self.stat = self.mid: self.status = 'caution' self.sound.play(True) self.auto_check_timer = delay(self.sound.bytes_to_seconds(len(self.sound))*2, self.auto_check) elif self.stat = self.low: self.status = 'danger' self.sound.play(True) self.auto_check_timer = delay(self.sound.bytes_to_seconds(len(self.sound)), self.auto_check) def check(self): if self.status = 'caution' and self.low= self.stat self.mid: #This will set the program to start a constant alarm when the stat level has dropped below caution self.auto_check_timer.cancel() if self.sound.is_playing: #to assist in setting up the caution to danger transition #a standard playing sound will have a timer running alongside it, so skip the next guard and return if self.auto_check_timer.is_alive() == False: #guard to make sure program doesn't catch every playing sound, should prevent repeated checks from recalling auto_check sound_duration =
Re: [Tutor] Passing a Variable
I've read your code. Frankly I don't understand your problem. I also don't see any occurrence of health. There isn't a reference to health here. My goal is to have this code act as a checker for health, fatigue, time_remaining, or any other sort of statistic you'd like to throw into it. My problem is that when I try: instance = Statistic(stat=health, sound=spam, low=1, mid=15, high=30) health can change elsewhere in the program, but the instance of statistic class won't automatically see it. Also your description of the program and the program itself is kinda overwhelming, and so much of that information is not relevant to your question. That makes it hard to understand the question. My apologies if this came across as verbose. I'm a newbie at all things python, so I'm still learning everything from code to conventions. You can simplify the above logic: Thank you for that. I will happily accept style suggestions whenever I can get them. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] passing a variable ?
It should look like this:fout = file('/home/cable/sandbox/%s' % savename, 'a''w')The variables come immediately after the string your formatting.On 10/19/06, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: I am stumped.I am trying to pass the variable 'savename' to a stringand get errors.can someone tell me why?Thanks to all on this list.(The problemhappens in the for loop 1st line)This is my error Traceback (most recent call last):File ./ArpAcl.py, line 39, in ?fout = file('/home/cable/sandbox/%s', 'a''w' % savename)TypeError: not all arguments converted during string formatting import pexpectimport getpassimport sys#Go through all the routers and gather Access-list or ARP information,return the info into it's own file. print '\n'print 'Router scrub will take approx 60 Seconds.'print '\n'print For the ARP list enter '1'print For the ACL list enter '2'print '\n'choice = input('Enter 1 or 2: ') print '\n'telpass = getpass.getpass('Please enter the telnet password: ')enablepass = getpass.getpass('Please enter the enable password: ')if choice == 1:command = 'show arp'savename = ' arp.txt'else:command = 'sh ip access-l'savename = 'acl.txt'print '\n'print '-' * 48print 'You will be notified when program is finished.'print '-' * 48x = open('/home/cable/router.list','r') routers = x.readlines()for i in routers:fout = file('/home/cable/sandbox/%s', 'a''w' % savename)c = pexpect.spawn('/usr/bin/telnet %s' %i)c.expect('Please Enter Password:') c.sendline(telpass +'\r')c.sendline('enable\r')c.expect('Password:')c.sendline(enablepass + '\r')c.expect('#')c.logfile = foutc.sendline('skip\r') c.expect('#')c.sendline(command + '\r')c.expect('#')fout.close()c.close()x.close()print '\n'print 'Finished!'print '\n'print 'File has been save to /home/cable/sandbox/%s' % savename raw_input('Press any key to exit')___Tutor maillist-Tutor@python.org http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] passing a variable ?
[EMAIL PROTECTED] wrote: I am stumped. I am trying to pass the variable 'savename' to a string and get errors. can someone tell me why? Thanks to all on this list. (The problem happens in the for loop 1st line) This is my error Traceback (most recent call last): File ./ArpAcl.py, line 39, in ? fout = file('/home/cable/sandbox/%s', 'a''w' % savename) TypeError: not all arguments converted during string formatting You are applying the formatting operator to the string 'aw' not to the path string. Try this: fout = file('/home/cable/sandbox/%s' % savename, 'a''w') Not sure why you have both 'a' and 'w' - which one do you want? Seems like you should pick one. Kent import pexpect import getpass import sys #Go through all the routers and gather Access-list or ARP information, return the info into it's own file. print '\n' print 'Router scrub will take approx 60 Seconds.' print '\n' print For the ARP list enter '1' print For the ACL list enter '2' print '\n' choice = input('Enter 1 or 2: ') print '\n' telpass = getpass.getpass('Please enter the telnet password: ') enablepass = getpass.getpass('Please enter the enable password: ') if choice == 1: command = 'show arp' savename = 'arp.txt' else: command = 'sh ip access-l' savename = 'acl.txt' print '\n' print '-' * 48 print 'You will be notified when program is finished.' print '-' * 48 x = open('/home/cable/router.list','r') routers = x.readlines() for i in routers: fout = file('/home/cable/sandbox/%s', 'a''w' % savename) c = pexpect.spawn('/usr/bin/telnet %s' %i) c.expect('Please Enter Password:') c.sendline(telpass +'\r') c.sendline('enable\r') c.expect('Password:') c.sendline(enablepass + '\r') c.expect('#') c.logfile = fout c.sendline('skip\r') c.expect('#') c.sendline(command + '\r') c.expect('#') fout.close() c.close() x.close() print '\n' print 'Finished!' print '\n' print 'File has been save to /home/cable/sandbox/%s' % savename raw_input('Press any key to exit') ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor