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 repe
Re: [Tutor] Passing a Variable
On Mon, Apr 4, 2011 at 7:27 AM, Ryan Strunk 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
> 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
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 = sel
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
[Tutor] Passing a Variable
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. 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 = self.sound.bytes_to_seconds(len(self.sound)) - self.sound.bytes_to_seconds(self.sound.position) self.auto_check_timer = delay(sound_duration, self.auto_check) return if self.auto_check_timer == False: #if the timer has never been called, call auto_check self.auto_check() return if self.auto_check_timer.is_alive == True: #there's already a timer running. return return #If it gets this far, it's because the timer already ran, the player is 'safe', and another check is being performed self.auto_check() ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: 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
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
[Tutor] passing a variable ?
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 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