Re: [Tutor] Passing a Variable

2011-04-04 Thread Lie Ryan
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

2011-04-04 Thread Andre Engels
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

2011-04-03 Thread Ryan Strunk
> 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

2011-04-03 Thread bob gailer

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

2011-04-03 Thread Steven D'Aprano
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

2011-04-03 Thread Ryan Strunk
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 ?

2006-10-19 Thread Kent Johnson
[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 ?

2006-10-19 Thread Jason Massey
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 ?

2006-10-19 Thread dpotter
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