Re: [Tutor] Class methods

2011-06-27 Thread Alan Gauld

"David Merrick"  wrote


Is it possible too have

crit1 = Critter("Dave")
crit2 = Critter("Sweetie")
farm = [crit1,crit2]  #List#

and then be able to use Critters methods on farm?


No, Marc has already answered that.


class Critter(object):

   """A virtual pet"""
   def __init__(self, name, hunger = 0, boredom = 0):

   # __ denotes private method
   def __pass_time(self):
   self.hunger += 1
   self.boredom += 1
   self.__str__()

   def __str__(self):
   print("Hunger is",self.hunger, "Boredom is " ,self.boredom)
   print("Unhappines is ",self.hunger + self.boredom," and Mood 
is

",self.mood)



This is a really bad idea. Please do not do this,
it will almost certainly lead to problems later.
__str__ should return a string. It should not print anything.

Then you can simply call

print (self)

at the end of the pass_time method

or call

print (farm[0])

in your external code.

HTH,


--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Class methods

2011-06-26 Thread Marc Tompkins
On Sun, Jun 26, 2011 at 7:12 PM, David Merrick  wrote:

> Is it possible too have
>
> crit1 = Critter("Dave")
> crit2 = Critter("Sweetie")
> farm = [crit1,crit2]  #List#
>
> and then be able to use Critters methods on farm?
>
> No.  farm is a list, and lists don't inherit the methods of the objects
inside them (imagine what a nightmare _that_ would be, especially since
lists can contain more than one type of object at any given time!)

Instead, you would refer to the members of the list:
farm[0].talk()
farm[1].talk()
etc.  Only you wouldn't generally hard-code those numbers; instead, you
could use the "for x in y" style:
for monster in farm:
monster.talk()
At this point, "monster" is one of your Critters.  When I need a looping
variable for a collection of custom objects, I like to use words that are
synonymous with, or at least related to, the name of my custom class.  It
helps me keep track of what's going on - if I use x and y all over the
place, I tend to get confused.

You could also use a more traditional, less-Pythonic approach:
for x in len(farm):
farm[x].talk()
But seriously, why would you want to use Python to imitate Visual Basic?

By the way, you shouldn't ever need to refer to Dave and Sweetie by their
hard-coded variable names, so instead of instead of creating "crit1, crit2",
why not simply create them as members of the list?
farm = []
for critter_name in ["Dave", "Sweetie"]:
farm.append(Critter(critter_name))
Now the variables don't have names per se, but you can still refer to them
by number if you need one in particular, or you can just loop over the list
with "for monster in farm".

Finally, maybe a dictionary would be more useful/intuitive than a list?
farm = []
for critter_name in ["Dave", "Sweetie"]:
farm[critter_name] = Critter(critter_name)
farm["Dave"].talk()

I do think that "farm" is going to be a little misleading as a name for a
collection of Critters; might I suggest "herd" or "swarm"?  Just a
thought...
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Class methods

2011-06-26 Thread David Merrick
Is it possible too have

crit1 = Critter("Dave")
crit2 = Critter("Sweetie")
farm = [crit1,crit2]  #List#

and then be able to use Critters methods on farm?

# Critter Caretaker
# A virtual pet to care for

class Critter(object):

"""A virtual pet"""
def __init__(self, name, hunger = 0, boredom = 0):
self.name = name
self.hunger = hunger
self.boredom = boredom

# __ denotes private method
def __pass_time(self):
self.hunger += 1
self.boredom += 1
self.__str__()

def __str__(self):
print("Hunger is",self.hunger, "Boredom is " ,self.boredom)
print("Unhappines is ",self.hunger + self.boredom," and Mood is
",self.mood)



@property
def mood(self):
unhappiness = self.hunger + self.boredom
if unhappiness < 5:
m = "happy"
elif 5 <= unhappiness <= 10:
m = "okay"
elif 11 <= unhappiness <= 15:
m = "frustrated"
else:
m = "mad"
return m

def talk(self):
print("I'm", self.name, "and I feel", self.mood, "now.\n")
self.__pass_time()


def eat(self):
food = int(input("Enter how much food you want to feed your critter:
"))
print("Brruppp.  Thank you.")
self.hunger -= food
# hunger = 0 at iniatition
# self.hunger = self.boredom - food
if self.hunger < 0:
self.hunger = 0
self.__pass_time()


def play(self):
fun = int(input("Enter how much fun you want your critter to have:
"))
print("Wheee!")
self.boredom -= fun
# boredom = 0 at iniatition
# self.boredom = self.boredom - fun
if self.boredom < 0:
self.boredom = 0
self.__pass_time()


def main():
crit_name = input("What do you want to name your critter?: ")
crit = Critter(crit_name)

choice = None
while choice != "0":
print \
("""
Critter Caretaker

0 - Quit
1 - Listen to your critter
2 - Feed your critter
3 - Play with your critter
""")

choice = input("Choice: ")
print()

# exit
if choice == "0":
print("Good-bye.")

# listen to your critter
elif choice == "1":
crit.talk()

# feed your critter
elif choice == "2":
crit.eat()

# play with your critter
elif choice == "3":
crit.play()

# some unknown choice
else:
print("\nSorry, but", choice, "isn't a valid choice.")

main()
("\n\nPress the enter key to exit.")



-- 
Dave Merrick

merrick...@gmail.com

Ph   03 3423 121
Cell 027 3089 169
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Class methods

2011-06-22 Thread Alan Gauld


"David Merrick"  wrote


Can someone show me how to code this correctly please?


We've been doing that but you are still making
some very basic mistakes which reflect a deep
misunderastanding of what you are doing. You
really should take several steps back and review
the use of variables and functions and then
reread the introductory material on classes
and objects. Until you get the basics right you
will struggle and even if somebody fixes all the
issues in this code, the minute you try another
program all the same problems will bite you.

That having been said I'll make some comments:


class Critter(object):

   """A virtual pet"""
   def __init__(self, name, hunger = 0, boredom = 0):
   self.name = name
   self.hunger = hunger
   self.boredom = boredom


This is OK.


   # __ denotes private method
   def __pass_time(self):
   self.hunger += 1
   self.boredom += 1
   self.__str__()


The last line does nothing useful. (It prints stuff just now
but that's because of a conceptual fault in your str method.
What you should really be saying here is:

print (self)


   def __str__(self):
   print("Hunger is",self.hunger, "Boredom is " ,self.boredom)
   print("Unhappines is ",self.hunger + self.boredom," and Mood 
is

",self.mood)


__str__ methods are supposed to return a string which
can be used (or printed) by other code. They should not
print anything themselves.

This should do something like:

return """Hunger is %s,
  Boredom is %s
  Unhappines is %s and
  Mood is%s""" % ( self.hunger,
  self.boredom,
  self.hunger+self.boredom,
  self.mood)


   @property
   def mood(self):
   unhappiness = self.hunger + self.boredom
   if unhappiness < 5:
   m = "happy"
   elif 5 <= unhappiness <= 10:
   m = "okay"
   elif 11 <= unhappiness <= 15:
   m = "frustrated"
   else:
   m = "mad"
   return m


OK


   def talk(self):
   for critter in farmlet:
   print("I'm", self.name, "and I feel", self.mood, 
"now.\n")

   self.__pass_time()


Problem: What is farmlet here? There is no farmlet in
the method. There is no self.farmlet you can access.
So now your class is tied to the external farmlet variable
in the global scope, making your class pretty much useless
in any other context. Also it will print the same message
as many times as there are critters in farmlet - 2 in this case.
But the message won't change because self still only
applies to the current object.

You are iterating over the critters in your main() function,
you don't need to do it inside the critter itself. Each critter
should only comment on its own state.

I'd also prefer that this returned a string too because
putting print statements inside methods limits the usefulness
of the class. How would it work in a GUI version for example?
Better to return a string and print that where you call it.


   def eat(self):
   food = int(input("Enter how much food you want to feed your 
critter:

"))
   print("Brruppp.  Thank you.")
   self.hunger -= food
   # hunger = 0 at iniatition
   # self.hunger = self.boredom - food
   if self.hunger < 0:
   self.hunger = 0
   self.__pass_time()


OK, I think


   def play(self):
   fun = int(input("Enter how much fun you want your critter to 
have:

"))
   print("Wheee!")
   self.boredom -= fun
   # boredom = 0 at iniatition
   # self.boredom = self.boredom - fun
   if self.boredom < 0:
   self.boredom = 0
   self.__pass_time()


OK, I think


def main():
   crit1 = Critter("Sweetie")
   crit2 = Critter("Dave")
   farmlet = [crit1,crit2]


OK so far, we have a list with two Critters


   choice = None
   while choice != "0":
   print \
   ("""
   Critter Caretaker

   0 - Quit
   1 - Listen to your critter
   2 - Feed your critter
   3 - Play with your critter
   """)

   choice = input("Choice: ")
   print()


Also OK we now have a choice and a loop.


   if choice == "0":
   print("Good-bye.")


And we exit so the program eventually stops,
which is good.


   elif choice == "1":
   for critter in farmlet:
   farmlet.talk()


But here we are asking the list to do stuiff which
is not good. It is the critters that talk. So you need
to send talk() to the critter not the list:

for critter in farmlet:
 critter.talk()


   # feed your critter
   elif choice == "2":
   farmlet.eat()


Again lists can't eat, you need to feed weither an
individual crittter - get the user to choose which?
- or feed all your critters using the same code
pattern as for talk above.


   # play with your critter
   elif choice == "3":
   f.play(farmlet)


You don't have an f and you don't now ha

Re: [Tutor] Class methods

2011-06-22 Thread Alan Gauld


"michael scott"  wrote 

you are using python 3 by your print statements, so I 
don't think you need the int() around your input, 


Yes he does because in Python 3 input is the same as raw_input 
in Python 2


even in python.2x input() was safe for numbers I believe 
(the whole list will rip my throat out if I'm wrong anyways


rip, rip, rip. :-)
In Python 2 input could be used for numbers but it was 
not "safe", which is why input was effectively removed 
in Python 3 and raw_input renamed to input. In Python 2 
input() evaluated whatever was typed as a Python expression 
which made it very unsafe. 



--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Class methods

2011-06-22 Thread michael scott
Just to add a little to Alexandre's answer.  You can keep most of the code the 
same just add in   
    farmlet[0].eat()
    farmlet[1].eat()

and it will be okay... kinda. Or you could rewrite it and  do it another 
way...  I'm guessing that you are using python 3 by your print statements, so I 
don't think you need the int() around your input, even in python.2x input() was 
safe for numbers I believe (the whole list will rip my throat out if I'm wrong 
anyways, lol), but in your while loop around line 82 you have all the 
conditions responding to a string, even thought you explicitly changed the 
input to an integer.

if choice == "0"


instead of 


if choice == 0:

so I got a continual output of 
('\nSorry, but', 3, "isn't a valid choice.")  

Now this does not get your program running the way you want it to, but it will 
start you off making the corrections you need. Just some things to think about, 
in line 113, when did you define class f?
in line 102, what are you trying to do, and are you telling it the right thing?
since you have 2 (or possibly more) critters you are taking care of, how does 
the player know which one he is feeding / talking to / playing with in your 
farmlet?

Anyways best of luck in your program, sounds pretty cool...

 

What is it about you... that intrigues me so?



From: Alexandre Conrad 
To: David Merrick 
Cc: tutor@python.org
Sent: Wednesday, June 22, 2011 6:48 PM
Subject: Re: [Tutor] Class methods

David,

2011/6/22 David Merrick :
>     # listen to your critter
>     elif choice == "1":
>     for critter in farmlet:
>     farmlet.talk()

You want to call .talk() on your "critter" instance which has the
.talk() method, not on farmlet (which is a list as the error message
states)

> Traceback (most recent call last):
>   File "I:/Python/programs/critter_farm4.py", line 117, in 
>     main()
>   File "I:/Python/programs/critter_farm4.py", line 103, in main
>     farmlet.talk()
> AttributeError: 'list' object has no attribute 'talk'

You will probably have a problem when calling talk() because it
references to the "farmlet" variable which doesn't exist in the scope
of your .talk() method.

HTH,
-- 
Alex | twitter.com/alexconrad
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Class methods

2011-06-22 Thread Alexandre Conrad
David,

2011/6/22 David Merrick :
>     # listen to your critter
>     elif choice == "1":
>     for critter in farmlet:
>     farmlet.talk()

You want to call .talk() on your "critter" instance which has the
.talk() method, not on farmlet (which is a list as the error message
states)

> Traceback (most recent call last):
>   File "I:/Python/programs/critter_farm4.py", line 117, in 
>     main()
>   File "I:/Python/programs/critter_farm4.py", line 103, in main
>     farmlet.talk()
> AttributeError: 'list' object has no attribute 'talk'

You will probably have a problem when calling talk() because it
references to the "farmlet" variable which doesn't exist in the scope
of your .talk() method.

HTH,
-- 
Alex | twitter.com/alexconrad
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Class methods

2011-06-22 Thread David Merrick
Can someone show me how to code this correctly please?

# Critter Caretaker
# A virtual pet to care for

class Critter(object):

"""A virtual pet"""
def __init__(self, name, hunger = 0, boredom = 0):
self.name = name
self.hunger = hunger
self.boredom = boredom

# __ denotes private method
def __pass_time(self):
self.hunger += 1
self.boredom += 1
self.__str__()

def __str__(self):
print("Hunger is",self.hunger, "Boredom is " ,self.boredom)
print("Unhappines is ",self.hunger + self.boredom," and Mood is
",self.mood)



@property
def mood(self):
unhappiness = self.hunger + self.boredom
if unhappiness < 5:
m = "happy"
elif 5 <= unhappiness <= 10:
m = "okay"
elif 11 <= unhappiness <= 15:
m = "frustrated"
else:
m = "mad"
return m

def talk(self):
for critter in farmlet:
print("I'm", self.name, "and I feel", self.mood, "now.\n")
self.__pass_time()


def eat(self):
food = int(input("Enter how much food you want to feed your critter:
"))
print("Brruppp.  Thank you.")
self.hunger -= food
# hunger = 0 at iniatition
# self.hunger = self.boredom - food
if self.hunger < 0:
self.hunger = 0
self.__pass_time()


def play(self):
fun = int(input("Enter how much fun you want your critter to have:
"))
print("Wheee!")
self.boredom -= fun
# boredom = 0 at iniatition
# self.boredom = self.boredom - fun
if self.boredom < 0:
self.boredom = 0
self.__pass_time()


##class Farm(Critter):
##def __init__(self,farmlet):
##   Critter.__init__(self,farmlet)
##   self.farmlet = farmlet
##
##def talk(self,farmlet):
##for critter in farmlet:
##print("Hello")
##Critter.talk(farmlet)

def main():
crit1 = Critter("Sweetie")
crit2 = Critter("Dave")
farmlet = [crit1,crit2]


choice = None
while choice != "0":
print \
("""
Critter Caretaker

0 - Quit
1 - Listen to your critter
2 - Feed your critter
3 - Play with your critter
""")

choice = input("Choice: ")
print()

# exit
if choice == "0":
print("Good-bye.")

# listen to your critter
elif choice == "1":
for critter in farmlet:
farmlet.talk()

# feed your critter
elif choice == "2":
farmlet.eat()

# play with your critter
elif choice == "3":
f.play(farmlet)

# some unknown choice
else:
print("\nSorry, but", choice, "isn't a valid choice.")

main()
("\n\nPress the enter key to exit.")

*Output*

Critter Caretaker

0 - Quit
1 - Listen to your critter
2 - Feed your critter
3 - Play with your critter

Choice: 1

Traceback (most recent call last):
  File "I:/Python/programs/critter_farm4.py", line 117, in 
main()
  File "I:/Python/programs/critter_farm4.py", line 103, in main
farmlet.talk()
AttributeError: 'list' object has no attribute 'talk'

-- 
Dave Merrick

merrick...@gmail.com

Ph   03 3423 121
Cell 027 3089 169
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Class methods

2011-06-22 Thread Alan Gauld
"David Merrick"  wrote 


class Critter(object):

   def __init__(self, name, hunger = 0, boredom = 0):
   def __pass_time(self):
   def __str__(self):
   @property
   def mood(self):
   def talk(self):
   def eat(self):
   def play(self):

class Farm(Critter):


I still don't think a Farm is a type of Critter...


   def __init__(self,farmlet):
  Critter.__init__(self,farmlet)


This will set the name to farmlet, which I don't 
think you want.



   def talk(self,farmlet):


You don't need to pass farmlet in since the 
class has farmlet stored inside it. 
You can access farmlet with self.farmlet.



   for critter in farmlet:
   print("Hello")
   Critter.talk(farmlet)


You want the instance to talk not the class.
So you need to use critter.talk() And the talk 
method does not take any arguments except 
self. What you are doing here is calling the 
class method with an instance value of farmlet.

ie self in that method gets the value of farmlet.


def main():
   crit1 = Critter("Sweetie")
   crit2 = Critter("Dave")
   farmlet = [crit1,crit2]
   f = Farm(farmlet)

   choice = None
   while choice != "0":
   print \
   ("""
   Critter Caretaker

   0 - Quit
   1 - Listen to your critter
   2 - Feed your critter
   3 - Play with your critter
   """)

   choice = input("Choice: ")
   print()

   # exit
   if choice == "0":
   print("Good-bye.")

   # listen to your critter
   elif choice == "1":
   f.talk(farmlet)

   # feed your critter
   elif choice == "2":
   f.eat(farmlet)


Note that f.eat is a method you inherit from Critter.
The Critter method does not take any arguments 
so this will fail.



   # play with your critter
   elif choice == "3":
   f.play(farmlet)


Same with f.play()


Traceback (most recent call last):
 File "D:/David/Python/programs/critter_farm3.py", line 72, in talk
   Critter.talk(farmlet)
 File "D:/David/Python/programs/critter_farm3.py", line 38, in talk
   print("I'm", self.name, "and I feel", self.mood, "now.\n")
AttributeError: 'list' object has no attribute 'name'


This is because you are accessing the method via 
the class and passing farmlet as the instance value
rather than sending the message to the innstance 
directly. Use


critter.talk()   # and no farmlet needed! 


HTH,


--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Class methods

2011-06-21 Thread David Merrick
# Critter Caretaker
# A virtual pet to care for

class Critter(object):

"""A virtual pet"""
def __init__(self, name, hunger = 0, boredom = 0):
self.name = name
self.hunger = hunger
self.boredom = boredom

# __ denotes private method
def __pass_time(self):
self.hunger += 1
self.boredom += 1
self.__str__()

def __str__(self):
print("Hunger is",self.hunger, "Boredom is " ,self.boredom)
print("Unhappines is ",self.hunger + self.boredom," and Mood is
",self.mood)



@property
def mood(self):
unhappiness = self.hunger + self.boredom
if unhappiness < 5:
m = "happy"
elif 5 <= unhappiness <= 10:
m = "okay"
elif 11 <= unhappiness <= 15:
m = "frustrated"
else:
m = "mad"
return m

def talk(self):
print("I'm", self.name, "and I feel", self.mood, "now.\n")
self.__pass_time()


def eat(self):
food = int(input("Enter how much food you want to feed your critter:
"))
print("Brruppp.  Thank you.")
self.hunger -= food
# hunger = 0 at iniatition
# self.hunger = self.boredom - food
if self.hunger < 0:
self.hunger = 0
self.__pass_time()


def play(self):
fun = int(input("Enter how much fun you want your critter to have:
"))
print("Wheee!")
self.boredom -= fun
# boredom = 0 at iniatition
# self.boredom = self.boredom - fun
if self.boredom < 0:
self.boredom = 0
self.__pass_time()


class Farm(Critter):
def __init__(self,farmlet):
   Critter.__init__(self,farmlet)
   self.farmlet = farmlet

def talk(self,farmlet):
for critter in farmlet:
print("Hello")
Critter.talk(farmlet)

def main():
crit1 = Critter("Sweetie")
crit2 = Critter("Dave")
farmlet = [crit1,crit2]
f = Farm(farmlet)

choice = None
while choice != "0":
print \
("""
Critter Caretaker

0 - Quit
1 - Listen to your critter
2 - Feed your critter
3 - Play with your critter
""")

choice = input("Choice: ")
print()

# exit
if choice == "0":
print("Good-bye.")

# listen to your critter
elif choice == "1":
f.talk(farmlet)

# feed your critter
elif choice == "2":
f.eat(farmlet)

# play with your critter
elif choice == "3":
f.play(farmlet)

# some unknown choice
else:
print("\nSorry, but", choice, "isn't a valid choice.")

main()
("\n\nPress the enter key to exit.")

*OUTPUT*

 Critter Caretaker

0 - Quit
1 - Listen to your critter
2 - Feed your critter
3 - Play with your critter

Choice: 1

Hello
Traceback (most recent call last):
  File "D:/David/Python/programs/critter_farm3.py", line 115, in 
main()
  File "D:/David/Python/programs/critter_farm3.py", line 101, in main
f.talk(farmlet)
  File "D:/David/Python/programs/critter_farm3.py", line 72, in talk
Critter.talk(farmlet)
  File "D:/David/Python/programs/critter_farm3.py", line 38, in talk
print("I'm", self.name, "and I feel", self.mood, "now.\n")
AttributeError: 'list' object has no attribute 'name'

I am trying to access Crit1 and Crit2 namr in farmlet
-- 
Dave Merrick

merrick...@gmail.com

Ph   03 3423 121
Cell 027 3089 169
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods as static methods?

2010-05-30 Thread Alex Hall
On 5/30/10, Alan Gauld  wrote:
> "Alex Hall"  wrote
>
>> that it will hit. I would like to not instantiate a Harpoon object,
>> just call the Harpoon's getImpactCoords method and pass it the
>> required arguments. Is this possible?
>
> Others have pointed out that
> a) This is possible using staticmetjhod or classmetjod decorators and
> b) it seems a strange choice since you would expect the ability to
> use more than one harpoon and hence be better with an instance...
>
> I will add that if you really want a class method then maybe
> you can do without the class completely and just use a function?
Yes, that is what I ended up doing for testing, but it works well and
I do not think I will be making missile classes, just put each missile
type in its own file in a weapons subfolder, then import "from weapons
import *" to import all weapon files.
>
> The usual reason for class methods is to operate on the
> class as a whole - ie all instances - it is not to provide
> functionality
> without any instances (except in languages without functions,
> like Java, which really use static methods as a kluge to cover
> their limitations!)
>
> And functioons are much easiert to write and manage than
> instanceless classes!
>
> HTH,
>
> --
> Alan Gauld
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
>
>
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>


-- 
Have a great day,
Alex (msg sent from GMail website)
mehg...@gmail.com; http://www.facebook.com/mehgcap
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods as static methods?

2010-05-30 Thread Alan Gauld

"Alex Hall"  wrote


that it will hit. I would like to not instantiate a Harpoon object,
just call the Harpoon's getImpactCoords method and pass it the
required arguments. Is this possible?


Others have pointed out that
a) This is possible using staticmetjhod or classmetjod decorators and
b) it seems a strange choice since you would expect the ability to
use more than one harpoon and hence be better with an instance...

I will add that if you really want a class method then maybe
you can do without the class completely and just use a function?

The usual reason for class methods is to operate on the
class as a whole - ie all instances - it is not to provide 
functionality

without any instances (except in languages without functions,
like Java, which really use static methods as a kluge to cover
their limitations!)

And functioons are much easiert to write and manage than
instanceless classes!

HTH,

--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods as static methods?

2010-05-29 Thread Mark Lawrence

Hi Alex, thanks for the response, please see below.

On 30/05/2010 02:50, Alex Hall wrote:

On 5/29/10, Mark Lawrence  wrote:

On 29/05/2010 20:49, Alex Hall wrote:

Hi all,
In Battleship, I have a weapons.py file, currently with just one
missile type (a Harpoon anti-ship missile). This Harpoon class defines
a getImpactCoords method, which returns all coordinates on the map
that it will hit. I would like to not instantiate a Harpoon object,
just call the Harpoon's getImpactCoords method and pass it the
required arguments. Is this possible? Thanks. Sorry if I got the terms
backwards in the subject; I can never remember which is static and
which is non-static.



Hi Alex,

See you're still going for it :)

I think that you're trying to build a Yamoto/Musashi before you've built
a raft from oil drums or whatever :)  If I'm wrong, I'll apologise here
and now.

I have built one app in Python and have experience in Java and
Javascript, as well as some in PHP; in fact, I am going into my fourth
year of college for a computer science degree in September. While they
have not done as much programming as I would like, I have had enough
that I can find the commonalities between languages and generally know
what I am looking for (make this public, turn that into a class
instead of an independent collection of vars...)
That said, I have no professional experience programming and do only
assigned problems and hobby-level programming. My Screenless Widgets
app is nearing beta testing and works to my satisfaction, but I am
sure there is much I could do to improve it. Still, everyone has to
start somewhere...
I say all this not to express any offense at your message - believe
me, none taken - but rather to tell everyone just where I am coming
from.


I should hope not, I used to be big-headed, but now I'm perfect :)



For a really great introduction to Python, I suggest diveintopython,
it's what got me going eight years ago.

I feel that I understand the basics; what I am running into are things
that crop up and I learn them as needed; if I learn a concept but then
never use it, I will forget it, or mix it up with a similar comcept in
another language, so I generally attack things by reading intro
tutorials, modifying them, and then continuing from there until I feel
that I can start my own project from scratch and figure out the pieces
as I go along.


I suggest that you do *NOT* understand the basics, at least wrt Python, 
otherwise you would not have placed your original queries on c.l.py, 
before being asked to move to this ng/ml.  Regardless of that, you're on 
*THE* finest group of mls/ngs going for getting very sound advice from 
some of the most highly respected guys/gals going.  And if you want some 
kind of feeling of industry experiences, subscribe to the Python 
bugs/development/ideas ngs/mls (if you haven't already done so) and 
you'll very rapidly get an idea of just how difficult software 
development can get.


As an example, look for the thread on comp.lang.python within the last 
24 hours from myself subject "xrange issue 7721".  A relatively simple 
thing you'd have thought, but read the background on the Python bug 
tracker, and you'll see it ain't quite that easy.


But then, what do I know, I've only 34 years industry experience, albeit 
slightly tempered over the last nine years by physical and mental ill 
health.




Kindest regards.

Mark Lawrence.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor






I'm now going to bed, as it's 04:08 BST and I'm absolutely shattered.

Kindest regards.

Mark Lawrence.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods as static methods?

2010-05-29 Thread Steven D'Aprano
On Sun, 30 May 2010 05:49:45 am Alex Hall wrote:
> Hi all,
> In Battleship, I have a weapons.py file, currently with just one
> missile type (a Harpoon anti-ship missile). This Harpoon class
> defines a getImpactCoords method, which returns all coordinates on
> the map that it will hit. I would like to not instantiate a Harpoon 
> object, just call the Harpoon's getImpactCoords method and pass it
> the required arguments.

I don't understand the logic here. Surely the impact coordinates depends 
on the individual missile (an instance)?


> Is this possible? Thanks. Sorry if I got the
> terms backwards in the subject; I can never remember which is static
> and which is non-static.


In Python terminology, a static method is an ordinary function that is 
called as a method from either a class or a class instance:

class C(object):
@staticmethod
def method(x):
return "Called with argument %s", % x

Note that the method does not receive an automatic instance argument 
(usually called self) when you call it.

A class method is like an ordinary method, except instead of receiving 
the instance (self) as the first argument, it receives the class 
(usually called cls):

class C(object):
@classmethod
def method(cls, x):
return "Called from class %s with argument %s", % (cls, x)

The method always receives the class, regardless of whether you call it 
from the class using C.method(x) or from an instance C().method(x).

You might also be interested in what I call "dualmethod", which passes 
the class as first argument if you call it from the class, and the 
instance if you call it from the instance:

http://code.activestate.com/recipes/577030-dualmethod-descriptor/




-- 
Steven D'Aprano
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods as static methods?

2010-05-29 Thread Alex Hall
On 5/29/10, Mark Lawrence  wrote:
> On 29/05/2010 20:49, Alex Hall wrote:
>> Hi all,
>> In Battleship, I have a weapons.py file, currently with just one
>> missile type (a Harpoon anti-ship missile). This Harpoon class defines
>> a getImpactCoords method, which returns all coordinates on the map
>> that it will hit. I would like to not instantiate a Harpoon object,
>> just call the Harpoon's getImpactCoords method and pass it the
>> required arguments. Is this possible? Thanks. Sorry if I got the terms
>> backwards in the subject; I can never remember which is static and
>> which is non-static.
>>
>
> Hi Alex,
>
> See you're still going for it :)
>
> I think that you're trying to build a Yamoto/Musashi before you've built
> a raft from oil drums or whatever :)  If I'm wrong, I'll apologise here
> and now.
I have built one app in Python and have experience in Java and
Javascript, as well as some in PHP; in fact, I am going into my fourth
year of college for a computer science degree in September. While they
have not done as much programming as I would like, I have had enough
that I can find the commonalities between languages and generally know
what I am looking for (make this public, turn that into a class
instead of an independent collection of vars...)
That said, I have no professional experience programming and do only
assigned problems and hobby-level programming. My Screenless Widgets
app is nearing beta testing and works to my satisfaction, but I am
sure there is much I could do to improve it. Still, everyone has to
start somewhere...
I say all this not to express any offense at your message - believe
me, none taken - but rather to tell everyone just where I am coming
from.
>
> For a really great introduction to Python, I suggest diveintopython,
> it's what got me going eight years ago.
I feel that I understand the basics; what I am running into are things
that crop up and I learn them as needed; if I learn a concept but then
never use it, I will forget it, or mix it up with a similar comcept in
another language, so I generally attack things by reading intro
tutorials, modifying them, and then continuing from there until I feel
that I can start my own project from scratch and figure out the pieces
as I go along.
>
> Kindest regards.
>
> Mark Lawrence.
>
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>


-- 
Have a great day,
Alex (msg sent from GMail website)
mehg...@gmail.com; http://www.facebook.com/mehgcap
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods as static methods?

2010-05-29 Thread Mark Lawrence

On 29/05/2010 20:49, Alex Hall wrote:

Hi all,
In Battleship, I have a weapons.py file, currently with just one
missile type (a Harpoon anti-ship missile). This Harpoon class defines
a getImpactCoords method, which returns all coordinates on the map
that it will hit. I would like to not instantiate a Harpoon object,
just call the Harpoon's getImpactCoords method and pass it the
required arguments. Is this possible? Thanks. Sorry if I got the terms
backwards in the subject; I can never remember which is static and
which is non-static.



Hi Alex,

See you're still going for it :)

I think that you're trying to build a Yamoto/Musashi before you've built 
a raft from oil drums or whatever :)  If I'm wrong, I'll apologise here 
and now.


For a really great introduction to Python, I suggest diveintopython, 
it's what got me going eight years ago.


Kindest regards.

Mark Lawrence.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods as static methods?

2010-05-29 Thread Lie Ryan
On 05/30/10 05:49, Alex Hall wrote:
> Hi all,
> In Battleship, I have a weapons.py file, currently with just one
> missile type (a Harpoon anti-ship missile). This Harpoon class defines
> a getImpactCoords method, which returns all coordinates on the map
> that it will hit. I would like to not instantiate a Harpoon object,
> just call the Harpoon's getImpactCoords method and pass it the
> required arguments. Is this possible? Thanks. Sorry if I got the terms
> backwards in the subject; I can never remember which is static and
> which is non-static.
> 

Yes you can make it a static method or class method:

class Harpoon(object):
@staticmethod
def inst(a, b, c):
print a, b, c
@classmethod
def cmeth(cls, a, b, c):
print cls
print a, b, c

Harpoon.inst(1, 2, 3)
Harpoon.cmeth(1, 2, 3)

the question is, why would you want to? getImpactCoords() doesn't seem
to be a function that makes sense without a missile instance (I may be
mistaken).

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] class methods as static methods?

2010-05-29 Thread Alex Hall
Hi all,
In Battleship, I have a weapons.py file, currently with just one
missile type (a Harpoon anti-ship missile). This Harpoon class defines
a getImpactCoords method, which returns all coordinates on the map
that it will hit. I would like to not instantiate a Harpoon object,
just call the Harpoon's getImpactCoords method and pass it the
required arguments. Is this possible? Thanks. Sorry if I got the terms
backwards in the subject; I can never remember which is static and
which is non-static.

-- 
Have a great day,
Alex (msg sent from GMail website)
mehg...@gmail.com; http://www.facebook.com/mehgcap
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods: using class vars as args?

2010-05-28 Thread Steven D'Aprano
On Fri, 28 May 2010 07:42:30 am Alex Hall wrote:
> Thanks for all the explanations, everyone. This does make sense, and
> I am now using the
> if(arg==None): arg=self.arg
> idea. It only adds a couple lines, and is, if anything, more explicit
> than what I was doing before.

You should use "if arg is None" rather than an equality test.

In this case, you are using None as a sentinel value. That is, you want 
your test to pass only if you actually receive None as an argument, not 
merely something that is equal to None.

Using "arg is None" as the test clearly indicates your intention:

The value None, and no other value, is the sentinel triggering special 
behaviour

while the equality test is potentially subject to false positives, e.g. 
if somebody calls your code but passes it something like this:

class EqualsEverything:
def __eq__(self, other):
return True

instead of None.



-- 
Steven D'Aprano
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods: using class vars as args?

2010-05-27 Thread Alex Hall
Thanks for all the explanations, everyone. This does make sense, and I
am now using the
if(arg==None): arg=self.arg
idea. It only adds a couple lines, and is, if anything, more explicit
than what I was doing before.

On 5/27/10, Mark Lawrence  wrote:
> On 23/05/2010 20:40, Alex Hall wrote:
>> Hello all,
>> I know Python reasonably well, but I still run into basic questions
>> which those over on the other python list request I post here instead.
>> I figure this would be one of them:
>> Why would this not work:
>>
>> class c(object):
>>   def __init__(self, arg1, arg2):
>>self.arg1=arg1
>>self.arg2=arg2
>>
>>   def doSomething(self, arg3=self.arg1):
>>...
>>
>> The above results in an error that "name 'self' is not defined". Why
>> can I not set the default values of a method's arguments to class vars
>> like that? Thanks!
>>
>>
> You've already had some explanations as to what happens, but what are
> you trying to achieve?  Why don't you forget about arg3 because it is
> arg1, which must exist by creating an instance of class c, or you
> wouldn't be able to call doSomething in the first place?
>
> HTH.
>
> Mark Lawrence
>
>
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>


-- 
Have a great day,
Alex (msg sent from GMail website)
mehg...@gmail.com; http://www.facebook.com/mehgcap
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods: using class vars as args?

2010-05-27 Thread Mark Lawrence

On 23/05/2010 20:40, Alex Hall wrote:

Hello all,
I know Python reasonably well, but I still run into basic questions
which those over on the other python list request I post here instead.
I figure this would be one of them:
Why would this not work:

class c(object):
  def __init__(self, arg1, arg2):
   self.arg1=arg1
   self.arg2=arg2

  def doSomething(self, arg3=self.arg1):
   ...

The above results in an error that "name 'self' is not defined". Why
can I not set the default values of a method's arguments to class vars
like that? Thanks!


You've already had some explanations as to what happens, but what are 
you trying to achieve?  Why don't you forget about arg3 because it is 
arg1, which must exist by creating an instance of class c, or you 
wouldn't be able to call doSomething in the first place?


HTH.

Mark Lawrence


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods: using class vars as args?

2010-05-27 Thread spir ☣
On Sun, 23 May 2010 15:40:13 -0400
Alex Hall  wrote:

> Hello all,
> I know Python reasonably well, but I still run into basic questions
> which those over on the other python list request I post here instead.
> I figure this would be one of them:
> Why would this not work:
> 
> class c(object):
>  def __init__(self, arg1, arg2):
>   self.arg1=arg1
>   self.arg2=arg2
> 
>  def doSomething(self, arg3=self.arg1):
>   ...
> 
> The above results in an error that "name 'self' is not defined". Why
> can I not set the default values of a method's arguments to class vars
> like that? Thanks!

Python gives you the answer (I'm not kidding): "name 'self' is not defined". 
"self" is not a magic name in python, unlike in some other languages, 
automagically receiving a value. It is just a name you can use for anything, 
like "self=1".

A *convention* tells that this name is used for the *target* of a message. For 
instance:
l = [3,1,2]
l.sort()
calls sort on the target l, which becomes the object on which sort applies. 
Right? Then, python magically (this is the only magic) adds l as first argument 
to the method sort of the list class, at call time. If sort were defined in 
python, its header could look like:
def sort(target_list, compare_function=None):
The convention requires "target_list" to be rather called "self".

In your code, nowhere is a variable called "self" defined, before you try to 
use it. Since this happens in a class def, it should be first defined outside 
(probably in the global scope). If you write "self=1" somewhere before the 
class def, python will stop complaining about "self"... but it will complain 
about "arg1"!

A solution for what I guess you're trying to do is:
def doSomething(self, arg3=None):
if arg3 is None then arg3=self.arg1
The reason is that your default value, not only is not a constant, but is a 
variable depending on the actual instance, at call time. The only handle 
available to address an instance is precisely as target of a method call. So, 
you can only define something (here a default value) that depends on the 
instance from *inside* a method body, where the handle exists (magically 
brought by python).

Hope it's clear.


Denis


vit esse estrany ☣

spir.wikidot.com
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods: using class vars as args?

2010-05-23 Thread Matthew Wood
Hey Alex,

What's happening is that you're still in "defining functions" mode on the
line
def doSomething(self, arg3=self.arg1):

self, which is really nothing more than a parameter being passed in (special
parameter, but a parameter none the less) hasn't been assigned a value yet.


Imagine this function definition:

def do_something(a, b, c=a+b):

The parameter instances haven't been instantiated yet.


Another way to look at it:

You haven't finished defining the class yet, so you can't access data
specific to an instance.


Not the most technical description, but it's certainly how I look at it.

--

I enjoy haiku
but sometimes they don't make sense;
refrigerator?


On Sun, May 23, 2010 at 1:40 PM, Alex Hall  wrote:

> Hello all,
> I know Python reasonably well, but I still run into basic questions
> which those over on the other python list request I post here instead.
> I figure this would be one of them:
> Why would this not work:
>
> class c(object):
>  def __init__(self, arg1, arg2):
>  self.arg1=arg1
>  self.arg2=arg2
>
>  def doSomething(self, arg3=self.arg1):
>  ...
>
> The above results in an error that "name 'self' is not defined". Why
> can I not set the default values of a method's arguments to class vars
> like that? Thanks!
>
>
> --
> Have a great day,
> Alex (msg sent from GMail website)
> mehg...@gmail.com; http://www.facebook.com/mehgcap
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods: using class vars as args?

2010-05-23 Thread Alan Gauld


"Alex Hall"  wrote


class c(object):
def __init__(self, arg1, arg2):
 self.arg1=arg1
 self.arg2=arg2

def doSomething(self, arg3=self.arg1):
 ...

The above results in an error that "name 'self' is not defined". Why
can I not set the default values of a method's arguments to class 
vars

like that? Thanks!


Because they are not class vars they are instance vars.
self.arg1 does not exist until after an instance has been
created and they have been set by __init__. At the time
the class is defined self.arg1 does not exist.

You could do

class c(object):
defArg = 42
def __init__(self, arg1, arg2):
   self.arg1=arg1

def doSomething(self, arg3=defArg):
 ...

HTH,


--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] class methods: using class vars as args?

2010-05-23 Thread Alex Hall
Hello all,
I know Python reasonably well, but I still run into basic questions
which those over on the other python list request I post here instead.
I figure this would be one of them:
Why would this not work:

class c(object):
 def __init__(self, arg1, arg2):
  self.arg1=arg1
  self.arg2=arg2

 def doSomething(self, arg3=self.arg1):
  ...

The above results in an error that "name 'self' is not defined". Why
can I not set the default values of a method's arguments to class vars
like that? Thanks!


-- 
Have a great day,
Alex (msg sent from GMail website)
mehg...@gmail.com; http://www.facebook.com/mehgcap
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods as argument

2007-02-10 Thread Kent Johnson
thomas coopman wrote:
> On Sat, 10 Feb 2007 09:04:15 -0500
> Kent Johnson <[EMAIL PROTECTED]> wrote:

>> If you do want to keep FooList then you should call 
>> SortedList.__init__() to set the compare function.
>> SortedList.__init__ is an unbound function so you call it like this:
>>SortedList.__init__(self, Foo.compare)
> This works.
> I think I'll need to reed some more about super because I thought I had
> to use super in this case.

You can use super() also but for simple cases I think it is fine to just 
call the superclass method directly. super() is intended to help with 
some of the difficulties of multiple inheritance but it has some 
difficulties of its own.

> I mostly need the sorted list, because I want to detect when a object
> is added with the same value of some item in the list and take
> appropriate actions.

If you don't really care about the order, then a dict mapping the value 
of interest to a list of items with that value might be easier to work with.

Kent

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods as argument

2007-02-10 Thread thomas coopman
On Sat, 10 Feb 2007 09:04:15 -0500
Kent Johnson <[EMAIL PROTECTED]> wrote:

> thomas coopman wrote:
> > 
> > also,
> > Is it better to use super in FooList? and how should I use it then?
> 
> Actually I would say that FooList is not pulling its weight.
> SortedList already allows specialization by the compare function, so
> to create the equivalent of a FooList you just call
> SortedList(Foo.compare).
I know that in this example it's rather useless to create FooList, but
the subclasses I have of SortedList have other specializations so I
will keep using them.

> 
> If you do want to keep FooList then you should call 
> SortedList.__init__() to set the compare function.
> SortedList.__init__ is an unbound function so you call it like this:
>SortedList.__init__(self, Foo.compare)
This works.
I think I'll need to reed some more about super because I thought I had
to use super in this case.

> 
> Another design you might want to consider - if you will always be 
> sorting each type of list by the same compare method - is to define a 
> __cmp__() method in each class that will be part of a SortedList and
> use plain comparison operators (< > etc) to do the compare.
That's the problem.  I define for most of my classes a __cmp__() method
but, some classes have another way of being sorted, and that's why I
give the compare method as an argument in SortedList

> 
> Finally note that Python's sort() function is very fast and flexible
> and it might be better just to sort the list when you need it to be
> sorted, rather than keeping it sorted. Or maybe what you really need
> is a heap (see the heapq module). If you really want to keep a sorted
> list, you should look at the bisect module, it might help.
I now use sort() when there is some data initially.  After creation, I
insert data with my own bisect method, I also use it to search the data.

I mostly need the sorted list, because I want to detect when a object
is added with the same value of some item in the list and take
appropriate actions.

> 
> Kent
> 

Thomas
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods as argument

2007-02-10 Thread Kent Johnson
thomas coopman wrote:

> Thank you for the explanation of bound and unbound methods.
> I understand that it is more common to use a bound method, but I don't
> think that I can use this because at the time I save the method, I don't
> know anything about the instances.

That would be an appropriate time to use unbound methods. From your 
original example it wasn't clear.
> 
> I use this for making a sorted list using any method you give as
> argument when you create the list.  This class only gets to know it's
> instances when you add them.
> 
> In [3]: class SortedList(object):
>...: def __init__(self, compare):
>...: self.compare = compare
>...: def __add_(self, object):
>...: for i in self.data:
>...: self.compare(object, i)
>...:

That looks OK so far.
> 
> In [4]: class FooList(SortedList):
>...: def __init__(self):
>...: self.compare = Foo.compare
> 
> 
> __add__ doesn't do anything here of course, it is just an example,
> but I don't think that I can use a bound method in this case?

No. You can use an unbound method or an ordinary function with two 
arguments.
> 
> also,
> Is it better to use super in FooList? and how should I use it then?

Actually I would say that FooList is not pulling its weight. SortedList 
already allows specialization by the compare function, so to create the 
equivalent of a FooList you just call SortedList(Foo.compare).

If you do want to keep FooList then you should call 
SortedList.__init__() to set the compare function. SortedList.__init__ 
is an unbound function so you call it like this:
   SortedList.__init__(self, Foo.compare)

Another design you might want to consider - if you will always be 
sorting each type of list by the same compare method - is to define a 
__cmp__() method in each class that will be part of a SortedList and use 
plain comparison operators (< > etc) to do the compare.

Finally note that Python's sort() function is very fast and flexible and 
it might be better just to sort the list when you need it to be sorted, 
rather than keeping it sorted. Or maybe what you really need is a heap 
(see the heapq module). If you really want to keep a sorted list, you 
should look at the bisect module, it might help.

Kent

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods as argument

2007-02-10 Thread thomas coopman
On Sat, 10 Feb 2007 07:55:54 -0500
Kent Johnson <[EMAIL PROTECTED]> wrote:

> thomas coopman wrote:
> > Hi,
> > 
> > I want to do something like this, don't know how to properly
> > explain it, so I just give you some example code
> > 
>  class Foo(object):
>   def method(self, arg):
>   print arg
> > 
>  def doSomething(object, func):
>   object.func("test")
> > 
>  object = Foo()
>  doSomething(object, Foo.method)
> > 
> > I want to execute the class method given as argument,
> > but this obvious doesn't work, but I don't know how to
> > get it work,
> 
> First a quick note - don't use object as a parameter or variable
> name, it will hide the definition of the built-in object class.
Yes, I know, it was a bad example
> 
> You are very close. Foo.method is called an 'unbound method' of class 
> Foo. The syntax for calling an unbound method is to pass a class 
> instance as the first argument, followed by the actual argument list.
> It is actually the same argument list that you use when you declare
> the function (starting with self).
> 
> So your example can be written this way:
> 
> In [4]: class Foo(object):
> ...: def method(self, arg):
> ...: print arg
> 
> In [6]: o=Foo()
> 
> In [8]: def doSomething(obj, func):
> ...: func(obj, "test")
> 
> In [9]: doSomething(o, Foo.method)
> test
> 
> 
> A more common way to do this is to use a 'bound method'. That is what 
> you get when you refer to instance.method instead of Class.method. A 
> bound method includes a reference to the particular instance and can
> be called like an ordinary function. Rather than passing the instance
> and the unbound method to doSomething(), just pass the bound method
> as a single argument:
> 

> In [10]: def doSomething(func):
> : func("test")
> 
> In [12]: doSomething(o.method)
> test
> 
> In summary:
> Class.method => unbound method, call with instance as first arg
> instance.method => bound method, call with normal argument list
> 
> Kent
> 

Thank you for the explanation of bound and unbound methods.
I understand that it is more common to use a bound method, but I don't
think that I can use this because at the time I save the method, I don't
know anything about the instances.

I use this for making a sorted list using any method you give as
argument when you create the list.  This class only gets to know it's
instances when you add them.

In [3]: class SortedList(object):
   ...: def __init__(self, compare):
   ...: self.compare = compare
   ...: def __add_(self, object):
   ...: for i in self.data:
   ...: self.compare(object, i)
   ...:

In [4]: class FooList(SortedList):
   ...: def __init__(self):
   ...: self.compare = Foo.compare


__add__ doesn't do anything here of course, it is just an example,
but I don't think that I can use a bound method in this case?

also,
Is it better to use super in FooList? and how should I use it then?

Thomas
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods as argument

2007-02-10 Thread Andrei
Hi Thomas,


thomas coopman wrote:

> I want to execute the class method given as argument,
> but this obvious doesn't work, but I don't know how to
> get it work,

Pass the method reference of the class as argument, like this:

 >>> class A(object):
... def __init__(self, x): self.x = x
... def dostuff(self, arg):
... print self.x
... print arg
...
 >>> def dostuff(obj, method):
... method(obj, 'blabla')
...
 >>> a = A(5)
 >>> dostuff(a, A.dostuff)
5 # this demonstates method has been called for instance a
blabla




Yours,

Andrei

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods as argument

2007-02-10 Thread Kent Johnson
thomas coopman wrote:
> Hi,
> 
> I want to do something like this, don't know how to properly explain it,
> so I just give you some example code
> 
 class Foo(object):
def method(self, arg):
print arg
> 
 def doSomething(object, func):
object.func("test")
> 
 object = Foo()
 doSomething(object, Foo.method)
> 
> I want to execute the class method given as argument,
> but this obvious doesn't work, but I don't know how to
> get it work,

First a quick note - don't use object as a parameter or variable name, 
it will hide the definition of the built-in object class.

You are very close. Foo.method is called an 'unbound method' of class 
Foo. The syntax for calling an unbound method is to pass a class 
instance as the first argument, followed by the actual argument list. It 
is actually the same argument list that you use when you declare the 
function (starting with self).

So your example can be written this way:

In [4]: class Foo(object):
...: def method(self, arg):
...: print arg

In [6]: o=Foo()

In [8]: def doSomething(obj, func):
...: func(obj, "test")

In [9]: doSomething(o, Foo.method)
test


A more common way to do this is to use a 'bound method'. That is what 
you get when you refer to instance.method instead of Class.method. A 
bound method includes a reference to the particular instance and can be 
called like an ordinary function. Rather than passing the instance and 
the unbound method to doSomething(), just pass the bound method as a 
single argument:

In [10]: def doSomething(func):
: func("test")

In [12]: doSomething(o.method)
test

In summary:
Class.method => unbound method, call with instance as first arg
instance.method => bound method, call with normal argument list

Kent

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] class methods as argument

2007-02-10 Thread thomas coopman
On Sat, 10 Feb 2007 22:10:52 +1000
Jonathan McManus <[EMAIL PROTECTED]> wrote:

> It's pretty easy to make this work, actually. The issue is in the
> "doSomething" method.
> 
> > >>>class Foo(object):
> > >>> def method(self, arg):
> > >>> print arg
> > 
> > >>>def doSomething(object, func):
> > >>> object.func("test")
> 
> Here, it's looking for a method of the "Foo" object (object) called
> "func" (AttributeError: 'Foo' object has no attribute 'func'), instead
> of replacing "func" with "Foo.method". 
> 
> What you need to do is:
> 
> >>> def doSomething (object, func):
> >>>   func(object, "test")
> 
> This means that you are calling the method (explicity passed as being
> a method of Foo), as well as supplying the actual object as the first
> argument (the required self for classes).
> 
> >>> object = Foo()
> >>> doSomething(object, Foo.method)
> test
> 
> Hope that helps.
> 


Thanks,
that I've didn't come up with that myself!
It's indeed easy!
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


[Tutor] class methods as argument

2007-02-10 Thread thomas coopman
Hi,

I want to do something like this, don't know how to properly explain it,
so I just give you some example code

>>>class Foo(object):
>>> def method(self, arg):
>>> print arg

>>>def doSomething(object, func):
>>> object.func("test")

>>>object = Foo()
>>>doSomething(object, Foo.method)

I want to execute the class method given as argument,
but this obvious doesn't work, but I don't know how to
get it work,
Is it possible?
and how?

Thanks

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor