Open Side Menu Go to the Top

01-02-2012 , 11:57 PM
Code:
class Property(object): 

    def prompt_init():
        return dict(square_feet=input("Enter the square feet: "),
            beds=input("Enter number of bedrooms: "),
            baths=input("Enter number of baths: "))
    prompt_init = staticmethod(prompt_init)
this is from a book i'm working through. what is the point of using a static method? is it just because the children aren't going to modify the method that you do this? in this example the children are houses and apartments that both require these variables from the user.
** Python Support Thread ** Quote
** Python Support Thread **
150% up to $2,000 Welcome Bonus on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** Python Support Thread **
01-03-2012 , 02:14 AM
Is the book in Python 2? Because after some googling and looking at documentation I'm not even sure it even does anything in Python 3
** Python Support Thread ** Quote
01-03-2012 , 05:24 AM
ha just wrote out a long post in quick reply and lost it.

it's from this book, http://www.amazon.com/Python-3-Objec...5579972&sr=8-3

he used it in one of the "case studies" at the end of chapter 3 on multiple inheritance, for code that would manage real estate properties. the code is really long and he kept using the same name for the methods in different classes and it made it really hard to understand. here is his explanation,

Quote:
We see something new in the prompt_init method. This method is made into a static method immediately after it is initially created. Static methods are associated only with a class (much like class variables), rather than a specific object instance. Hence, they have no self argument. Because of this, the super keyword won't work (there is no parent object, only a parent class), so we simply call the static method on the parent class directly.
i'm still not sure what to make of it, but i managed to extract the basic idea of what he was doing and rewrite some code to play around with it. in his code he had what I wrote as childsomething() and something() both named the same, making it harder to decipher what the hell was going on. i think they are supposed to be the same for polymorphism/duck typing reasons but for this it doesn't matter. i'll have to look at it again tomorrow.

Code:
class Person(object):
	def something():
		print ('parent something')
		return dict(a=input('a: '), b=input('b: '))
	something = staticmethod(something)

class Man(Person):
	def childsomething():
		print ('child something')
		parentdict = Person.something()
		z = dict(c=input('c: '))
		parentdict.update(z)
		return parentdict
	childsomething = staticmethod(childsomething)
	
greg = Man()
print (greg.childsomething)
x = greg.childsomething()
print (x)
z = greg.something()
print (z)
print (x)
** Python Support Thread ** Quote
01-07-2012 , 02:59 AM
Quote:
Originally Posted by RoundTower
I meant you should simply do c = 1000 - a - b. Once you know a and b, you don't need to test every possible value of c to see if a + b + c = 1000.
That doesn't work. The test isn't a + b + c == 1000, it's a*a + b*b == c*c for a + b + c < 1000.

Quote:
Originally Posted by daveT
My solution still leans on that horrid sqrt() function
There are of course more efficient algorithms to solve the problem, but for this one there's an quick way to speed up the sqrt test. In hexadecimal all perfect squares end in 0, 1, 4 or 9, thus you can sieve out 3/4 of numbers before you take the sqrt. Use a fast bit operation to grab the last hex digit and only take the sqrt if it's one of those numbers.

Instead of this...

Code:
def isSquare(n):
  return int(sqrt(n)) ** 2 == n
Do something like this...

Code:
def isSquare(n):
  h = n & 0xF
  if h==0 or h==1 or h==4 or h==9:
    return int(sqrt(n)) ** 2 == n
  else:
    return False
There are of course more efficient algorithms to test for a perfect square as well, but this one is quick and easy to implement. If you don't care about how it's done and just want a fast implementation use gmpy.

RoundTower is right too about the sqrt test being invalid for large numbers. Round off error for floats can cause the sqrt function to return a value that's "supposed" to be x.0 as (x-1).999999 or x.000001 where casting it as an int (or taking it mod 1) may return the "wrong" result. This isn't too big a problem with sqrts, but can be terrible for cube roots and other fractional powers that can't be represented exactly as a float in decimal (actually binary I guess?). You can approximate the test to arbitrary precision with a tolerance by doing something like...

Code:
def isSquare(n):
  tol = 1e-6
  test = 0.5 - sqrt(n) % 1
  if 0.5 - abs(test) < tol:
    return True
  else:
    return False
But there are more rules like the hex trick above which allow you to evaluate the test exactly for any size int. They just require a more thorough implementation, which I'm sure gmpy does.

ETA: My last code snippet is kinda bad since, given the distribution of square roots, sqrt(n) is more likely to return x.000001 than (x-1).999999 but the point is valid.

Last edited by Neuge; 01-07-2012 at 03:13 AM.
** Python Support Thread ** Quote
01-07-2012 , 11:01 AM
Quote:
Originally Posted by Neuge
That doesn't work. The test isn't a + b + c == 1000
http://projecteuler.net/problem=9
** Python Support Thread ** Quote
01-07-2012 , 12:00 PM
Oops. I skimmed and thought the whole post was about problem 39. Ok ignore that part.
** Python Support Thread ** Quote
01-07-2012 , 09:28 PM
Quote:
Originally Posted by e i pi
ha just wrote out a long post in quick reply and lost it.

it's from this book, http://www.amazon.com/Python-3-Objec...5579972&sr=8-3

he used it in one of the "case studies" at the end of chapter 3 on multiple inheritance, for code that would manage real estate properties. the code is really long and he kept using the same name for the methods in different classes and it made it really hard to understand. here is his explanation,



i'm still not sure what to make of it, but i managed to extract the basic idea of what he was doing and rewrite some code to play around with it. in his code he had what I wrote as childsomething() and something() both named the same, making it harder to decipher what the hell was going on. i think they are supposed to be the same for polymorphism/duck typing reasons but for this it doesn't matter. i'll have to look at it again tomorrow.

Code:
class Person(object):
	def something():
		print ('parent something')
		return dict(a=input('a: '), b=input('b: '))
	something = staticmethod(something)

class Man(Person):
	def childsomething():
		print ('child something')
		parentdict = Person.something()
		z = dict(c=input('c: '))
		parentdict.update(z)
		return parentdict
	childsomething = staticmethod(childsomething)
	
greg = Man()
print (greg.childsomething)
x = greg.childsomething()
print (x)
z = greg.something()
print (z)
print (x)
I'm confused by your question?

After some searching around, I think he must have taught this in reverse order.

First, you should have been exposed to "self", "other", and "_init_."

What he did was try to show you class functions equivalent to:

def myfun():

myfun()

instead of

def myfun(arg):

myfun(x)

I think that the staticmethod() function allows you to call a class w/o actually initializing it with arguments. He is also throwing a ton of concepts at you in this code, so it's a tad hard to figure out what or why you are doing what you are doing (or even modifying the code to correctly reflect what he is doing).

Also, why did you pick this one up instead of the Lutz book?
** Python Support Thread ** Quote
01-07-2012 , 11:58 PM
Sorry, I wrote that code more for myself to figure out what staticmethod did.

Quote:
I think that the staticmethod() function allows you to call a class w/o actually initializing it with arguments.
Yep, the actual example in the book where he throws this out is like 80 lines long and I couldn't figure out what was going on or what purpose it served.

Do you like the Lutz book? It has poor reviews on amazon. This book is kind of weird. It is more about designing applications with OOP and the big picture than just listing off every in and out of the language. Specifically it has two chapters on "design patterns" that I haven't come across in other books.
** Python Support Thread ** Quote
01-08-2012 , 12:19 AM
http://pastebin.com/gzBXzjQK

here is the case study that I was having trouble with. no comments because the text explains every couple blocks of code.

Last edited by e i pi; 01-08-2012 at 12:29 AM. Reason: obv not expecting anyone to actually read it, just showing why it was a mind f to decipher
** Python Support Thread ** Quote
01-08-2012 , 02:56 AM
Can you copy/paste an actual working code?

It's 191 lines and had an indentation error in it. I fixed it, ran it, and nothing happens.

No need for the comments in the code. It's pretty self-explanatory.

I added this line to your code:

Code:
get_valid_input('abcdef', 'yes')
and got this:

Code:
>>> 
abcdef (y, e, s)

I don't think it matters which language you use to learn OOP if that is your aim in picking up this book. I know there are entire books dedicated to design patterns, though they usually use more hard-core OOP languages like Java. OOP in Python feels like it was added on with little thought, but maybe that's my opinion.
** Python Support Thread ** Quote
01-08-2012 , 05:00 AM
all the code does is allow an "agent" to add specific properties (house or apartment for rent or purchase) and their details and then display them. either import the module in an IDE or add this,

Code:
agent = Agent()
agent.add_property()
agent.display_properties()
** Python Support Thread ** Quote
01-08-2012 , 10:41 AM
So, something else I just learned from Project Euler: I started my Problem 44 solution and went to make a sandwich or something and when I came back the answer appeared literally the instant I was going to stop it and try something else. My usual route in this situation is to submit the answer anyway but look at the forum thread to see how it could be improved and saw someone else using Python made a post to the effect of "It's weird, I tried changing the set to a list and suddenly my solution took eight minutes instead!" So I tried the inverse, switching a list to a set and...it went from nearly six minutes to 1.37 seconds! (fwiw I had a list because I mistakenly thought the order mattered at first, though I was never sorting it; I was appending in ascending order as I needed more elements. The only operations I did in either version were appending and iterating)
** Python Support Thread ** Quote
01-08-2012 , 05:31 PM
I've spent about 20 minutes on this, and I conclude that the staticmethod() is really nothing more than syntactic sugar and perhaps helpful in debugging.

If I comment out the method, as I did in the Rental class:

Code:
class Rental:
	def __init__(self, furnished='', utilities='',
			rent='', **kwargs):
		super().__init__(**kwargs)
		self.furnished = furnished
		self.rent = rent
		self.utilities = utilities

	def display(self):
		super().display()
		print("RENTAL DETAILS")
		print("rent: {}".format(self.rent))
		print("estimated utilities: {}".format(
			self.utilities))
		print("furnished: {}".format(self.furnished))

	def prompt_init():
		return dict(
			rent=input("What is the monthly rent? "),
			utilities=input(
				"What are the estimated utilities? "),
			furnished = get_valid_input(
				"Is the property furnished? ",
					("yes", "no")))
	#prompt_init = staticmethod(prompt_init)
It works just fine.

There is another area that hints at this. I'm not sure if you made a transcription mistake or if he wrote it like this, but if this method was not syntactic sugar, this would probably throw an indentation error, but it doesn't:



Code:
class Purchase:
	def __init__(self, price='', taxes='', **kwargs):
		super().__init__(**kwargs)
		self.price = price
		self.taxes = taxes

	def display(self):
		super().display()
		print("PURCHASE DETAILS")
		print("selling price: {}".format(self.price))
		print("estimated taxes: {}".format(self.taxes))

	def prompt_init():
		return dict(
			price=input("What is the selling price? "),
			taxes=input("What are the estimated taxes? "))
		prompt_init = staticmethod(prompt_init)
As you can see, the last line of this code reads:

Code:
def prompt_init():
		return dict(
			price=input("What is the selling price? "),
			taxes=input("What are the estimated taxes? "))
		prompt_init = staticmethod(prompt_init)
thus, the prompt_init is calling nothing at this point.

To experiment further, I also added this:

Code:
if __name__ == "__main__":
        agent = Rental()
        agent.display()
        agent.prompt_init()
and threw an error. In this case, I had to uncomment the staticmethod() call to let the class print out without calling an error:

Code:
RENTAL DETAILS
rent: 
estimated utilities: 
furnished: 
Traceback (most recent call last):
  File "C:\Documents and Settings\d\Desktop\fd.py", line 198, in <module>
    agent.prompt_init()
TypeError: prompt_init() takes no arguments (1 given)
when staticmethod() is uncommented and the super() is commented out, the output is:

Code:
RENTAL DETAILS
rent: 
estimated utilities: 
furnished: 
What is the monthly rent? 6
What are the estimated utilities? d
Is the property furnished?  (yes, no) yes
>>>
but you see that the code is sort of broken


I think you can probably comment out all the staticmethods in this code and have it work properly assuming you do not want to call a class by itself.

The code isn't well sanitized either. For example, I can answer:

"How many square feet:" as k w/o it asking me to enter an integer (if that is what he wanted in this case).

I'm sort of mystified at how he managed to get super() to work correctly in this code, since there is no specified inheritance, but super() is a massive mind-****, so it's possible I am confused for no good reason here.

Interesting blog linked from SO on super():

http://www.artima.com/weblogs/viewpo...?thread=237121

Last edited by daveT; 01-08-2012 at 05:44 PM. Reason: Yikes, didn't finish this the first time, or the second, or....
** Python Support Thread ** Quote
01-08-2012 , 08:09 PM
I commented out all the staticmethod() and the code seems to work just fine for now.

I want to refactor all of this though:

Code:

class HouseRental(Rental, House):
	def prompt_init():
		init = House.prompt_init()
		init.update(Rental.prompt_init())
		return init
	#prompt_init = staticmethod(prompt_init)

class ApartmentRental(Rental, Apartment):
	def prompt_init():
		init = Apartment.prompt_init()
		init.update(Rental.prompt_init())
		return init
	#prompt_init = staticmethod(prompt_init)

class ApartmentPurchase(Purchase, Apartment):
	def prompt_init():
		init = Apartment.prompt_init()
		init.update(Purchase.prompt_init())
		return init
	#prompt_init = staticmethod(prompt_init)

class HousePurchase(Purchase, House):
	def prompt_init():
		init = House.prompt_init()
		init.update(Purchase.prompt_init())
		return init
	#prompt_init = staticmethod(prompt_init)
** Python Support Thread ** Quote
01-08-2012 , 08:43 PM
Quote:
Originally Posted by daveT
To experiment further, I also added this:

Code:
if __name__ == "__main__":
        agent = Rental()
        agent.display()
        agent.prompt_init()
and threw an error. In this case, I had to uncomment the staticmethod() call to let the class print out without calling an error:
this should make it clear to you what staticmethod does. hint: it's not "syntactic sugar" for an empty line of code.
** Python Support Thread ** Quote
01-08-2012 , 09:24 PM
Yeah, I was more correct in the earlier post irt to what staticmethod is, but in the case of the code from the book, the staticmethod() doesn't seem to be doing anything vital unless you want to have it there for debugging.

I found this article that seems to explain exactly what this decorator function does:

http://arunnambyar.blogspot.com/2010...mentation.html
** Python Support Thread ** Quote
01-08-2012 , 09:56 PM
Quote:
Originally Posted by daveT

[code]

There is another area that hints at this. I'm not sure if you made a transcription mistake or if he wrote it like this, but if this method was not syntactic sugar, this would probably throw an indentation error, but it doesn't:

Code:
def prompt_init():
		return dict(
			price=input("What is the selling price? "),
			taxes=input("What are the estimated taxes? "))
		prompt_init = staticmethod(prompt_init)
thus, the prompt_init is calling nothing at this point.
this won't cause an indentation error because the indentation matches a previous indent level just fine, and it won't cause a ValueError because it is never evaluated. When the function is defined, the compiler doesn't know that you won't have a variable called prompt_init in the global scope.

I'm not sure what you could mean by saying the staticmethod call "doesn't seem to be doing anything vital unless you want to have it there for debugging". It's no more or less vital than any other line in the code, and it has nothing whatsoever to do with debugging.
** Python Support Thread ** Quote
01-08-2012 , 10:23 PM
Yeah, staticmethod is definitely not syntactic sugar (unlike the @staticmethod decorator which is, as are all decorators).

This example should make clear the difference between static and non-static methods:

Code:
class Foo:
    def not_static(self):
        print "hi I'm not static"
        
class Bar:
    def im_static():
        print "a-ok from here"
    im_static = staticmethod(im_static)
    
    
f = Foo()
f.not_static() # no problem
Bar.im_static() #no problem
Foo.not_static()         #throws an unbound method exception
edit: some good discussion here: http://stackoverflow.com/questions/1...thod-in-python
** Python Support Thread ** Quote
01-09-2012 , 10:05 PM
Interesting stuff. I was trying to reverse engineer the idea, but alas, I was off.

Why does the entire program work just fine when the staticmethods are commented out? I find this confusing.

I get conceptually what the staticmethod is doing, but I don't get what the author of this code was trying to demonstrate. I think your guy's examples are much better, because these examples illustrate exactly why it would be needed and exactly what happens if it is not used.

Was that a bad example code or am I missing something obvious? I want to rewrite that program and figure out if there is a better way to write it. I'll post it when I am done.
** Python Support Thread ** Quote
01-09-2012 , 10:18 PM
Quote:
Originally Posted by Neko
Yeah, staticmethod is definitely not syntactic sugar (unlike the @staticmethod decorator which is, as are all decorators).

This example should make clear the difference between static and non-static methods:

Code:
class Foo:
    def not_static(self):
        print "hi I'm not static"
        
class Bar:
    def im_static():
        print "a-ok from here"
    im_static = staticmethod(im_static)
    
    
f = Foo()
f.not_static() # no problem
Bar.im_static() #no problem
Foo.not_static()         #throws an unbound method exception
edit: some good discussion here: http://stackoverflow.com/questions/1...thod-in-python
The conclusions of that thread are all over the place. They sort of suggest it isn't particularly needed and serves as a stylistic choice, but then there is argument that it is needed, then it is sort of needed, then it isn't really used much in the Python source and then it is sort of used, and...

There's a lot of threads on this topic:

http://stackoverflow.com/search?q=staticmethod
** Python Support Thread ** Quote
01-10-2012 , 02:32 AM
Quote:
Originally Posted by daveT
Was that a bad example code or am I missing something obvious? I want to rewrite that program and figure out if there is a better way to write it. I'll post it when I am done.
I think the author was mostly just showing that staticmethod exists and demonstrating that super() doesn't work on it. The multiple inheritance might have also been a problem for normal class methods, specifically the order in which the parent methods would be called (ie the program would ask for inputs out of order).

The thing is the author wasn't just trying to show what a static method does in this case study. This was at the end of a chapter that covered super(), multiple inheritance and polymorphism. So he threw all that **** in to one stupid example, after expressing that you probably shouldn't use multiple inheritance unless you have to.
** Python Support Thread ** Quote
01-10-2012 , 04:00 AM
Quote:
Originally Posted by daveT
I commented out all the staticmethod() and the code seems to work just fine for now.

I want to refactor all of this though:

Code:

class HouseRental(Rental, House):
	def prompt_init():
		init = House.prompt_init()
		init.update(Rental.prompt_init())
		return init
	#prompt_init = staticmethod(prompt_init)
This should cause an error anytime the method is called (this function takes 0 arguments, 1 given). If it isn't called in the program it will still run.
** Python Support Thread ** Quote
01-16-2012 , 08:57 PM
Code:
import time

def log_calls(func):
    def wrapper(*args, **kwargs):
        now = time.time()
        print("Calling {0} with {1} and {2}".format(
            func.__name__, args, kwargs))
        return_value = func(*args, **kwargs)
        print("Executed {0} in {1}ms".format(
            func.__name__, time.time() - now))
        return return_value
    return wrapper

@log_calls
def test1(a,b,c):
    print("\ttest1 called")

test1(1,2,3)
is the "wrapper" function nested within "log_calls" just to keep it from executing when the @log_calls decorator is used on "test1"? or is there some other reason for this?
** Python Support Thread ** Quote
01-16-2012 , 10:08 PM
think of it this way: why is 'now' declared inside the function call as opposed to, say, being a global variable?
** Python Support Thread ** Quote
01-18-2012 , 12:44 AM
Quote:
Originally Posted by e i pi
Code:
import time

def log_calls(func):
    def wrapper(*args, **kwargs):
        now = time.time()
        print("Calling {0} with {1} and {2}".format(
            func.__name__, args, kwargs))
        return_value = func(*args, **kwargs)
        print("Executed {0} in {1}ms".format(
            func.__name__, time.time() - now))
        return return_value
    return wrapper

@log_calls
def test1(a,b,c):
    print("\ttest1 called")

test1(1,2,3)
is the "wrapper" function nested within "log_calls" just to keep it from executing when the @log_calls decorator is used on "test1"? or is there some other reason for this?
Functions are data.

http://en.wikipedia.org/wiki/Closure_(computer_science)
** Python Support Thread ** Quote
** Python Support Thread **
150% up to $2,000 Welcome Bonus on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** Python Support Thread **

      
m