Velocity Reviews > Feature suggestion -- return if true

# Feature suggestion -- return if true

Chris Angelico
Guest
Posts: n/a

 04-18-2011
On Mon, Apr 18, 2011 at 12:04 PM, Dave Angel <(E-Mail Removed)> wrote:
> On 01/-10/-28163 02:59 PM, Chris Angelico wrote:
>>
>> *<snip>
>>
>> Sure. In my (somewhat contrived) example of factorials, that's going
>> to be true (apart from 0! = 0); and if the function returns a string
>> or other object rather than an integer, same thing. If there's the

>
> Just to be pedantic, by any reasonable definition, 0! == one, not zero.
>
> One reference: *http://en.wikipedia.org/wiki/Factorial
> 3rd sentence.

Hm! I never thought to check the definition... I just coded it up
quickly, and didn't even consider the possibility of a zero return
until the cache's loophole was challenged. Guess with a more correct
definition of factorial, it's even safer in the cache.

Question: How many factorial functions are implemented because a
program needs to know what n! is, and how many are implemented to
demonstrate recursion (or to demonstrate the difference between
iteration and recursion)?

ChrisA

Aahz
Guest
Posts: n/a

 04-18-2011
In article <(E-Mail Removed)>,
D'Arcy J.M. Cain <(E-Mail Removed)> wrote:
>On Sun, 17 Apr 2011 16:21:53 +1200
>Gregory Ewing <(E-Mail Removed)> wrote:
>> My idiom for fetching from a cache looks like this:
>>
>> def get_from_cache(x):
>> y = cache.get(x)
>> if not y:
>> y = compute_from(x)
>> cache[x] = y
>> return y

>
>I prefer not to create and destroy objects needlessly.
>
> def get_from_cache(x):
> if not x in cache:
> cache[x] = compute_from(x)
> return cache[x]

Aside from Steven's entirely appropriate pointed question, I find this

if x not in cache:

Without testing, I'm not sure, but I believe it's more efficient, too
(creates fewer bytecodes).
--
Aahz ((E-Mail Removed)) <*> http://www.pythoncraft.com/

"At Resolver we've found it useful to short-circuit any doubt and just
refer to comments in code as 'lies'. "
--Michael Foord paraphrases Christian Muirhead on python-dev, 2009-03-22

Gregory Ewing
Guest
Posts: n/a

 04-19-2011
Chris Angelico wrote:

> Question: How many factorial functions are implemented because a
> program needs to know what n! is, and how many are implemented to
> demonstrate recursion (or to demonstrate the difference between
> iteration and recursion)?

A related question is how often factorial functions are even
*used* in real code.

I can think of two uses for factorials off the top of my

* Coefficients of polynomials resulting from Taylor expansions.
In that case you probably have a loop that's calculating the
numerators and denominators iteratively, and the factorial
is folded into that. Or you're looking up the coefficients in
a table and not calculating factorials at all.

* Combinations and permutations -- again, the factorials are
probably folded into a loop that calculates the result in a
more direct and efficient way.

--
Greg

Jussi Piitulainen
Guest
Posts: n/a

 04-19-2011
Gregory Ewing writes:
> Chris Angelico wrote:
>
> > Question: How many factorial functions are implemented because a
> > program needs to know what n! is, and how many are implemented to
> > demonstrate recursion (or to demonstrate the difference between
> > iteration and recursion)?

(I can't get to the parent directly, so I follow up indirectly.)

Factorials become an interesting demonstration of recursion when done
well. There's a paper by Richard J. Fateman, citing Peter Luschny:

<http://www.cs.berkeley.edu/~fateman/papers/factorial.pdf>
<http://www.luschny.de/math/factorial/FastFactorialFunctions.htm>

Fateman's "major conclusion is that you should probably not use the
'naive' factorial programs for much of anything". I take this to
include their use as examples of recursion, unless the purpose is to
make the idea of recursion look bad.

Chris Angelico
Guest
Posts: n/a

 04-19-2011
On Tue, Apr 19, 2011 at 4:42 PM, Jussi Piitulainen
<(E-Mail Removed)> wrote:
> Factorials become an interesting demonstration of recursion when done
> well. There's a paper by Richard J. Fateman, citing Peter Luschny:
>
> <http://www.cs.berkeley.edu/~fateman/papers/factorial.pdf>
> <http://www.luschny.de/math/factorial/FastFactorialFunctions.htm>
>
> Fateman's "major conclusion is that you should probably not use the
> 'naive' factorial programs for much of anything". I take this to
> include their use as examples of recursion, unless the purpose is to
> make the idea of recursion look bad.

"
And here is an algorithm which nobody needs, for the Simple-Minded only:
long factorial(long n) { return n <= 1 ? 1 : n * factorial(n-1); } Do
not use it if n > 12.
"

I suppose the n > 12 issue is based on the assumption that
sizeof(long)==4. That's not an algorithmic question, that's a return
type issue... not to mention a rather naive assumption. 64-bit
integers let you go to n == 20 (iirc), and if you go bignum, even that
simple algorithm will be fine for up to n == 500 or so without stack
issues.

But sometimes you need a simple and well-known algorithm to
demonstrate a language feature with. Maybe we should switch to
Fibonacci instead... Anyone for caramel sauce?

http://www.dangermouse.net/esoteric/chef_fib.html

(As a side point, I have become somewhat noted around the house for
always saying "Fibonacci" whenever caramel sauce is mentioned...)

Chris Angelico

Thomas Rachel
Guest
Posts: n/a

 04-21-2011
Am 13.04.2011 01:06, schrieb Ethan Furman:

> --> def func():
> --> var1 = something()
> --> var2 = something_else('this')
> --> return? var1.hobgle(var2)
> --> var3 = last_resort(var1)
> --> return var3.wiglat(var2)

This makes me think of a decorator which can mimic the wantend behaviour:

def getfirst(f):
from functools import wraps
@wraps(f)
def func(*a, **k):
for i in f(*a, **k):
if i: return i
return func

# [BTW: a kind of "return decorator" would be nice here ]

@getfirst
def func():
var1 = something()
var2 = something_else('this')
yield var1.hobgle(var2)
var3 = last_resort(var1)
yield var3.wiglat(var2)
yield "Even that did not work."

evaluate: maybe the func does return tuples of which only the 2nd part
is relevant concerning the check. Then just do

def getfirst(f):
from functools import wraps
@wraps(f)
def func(*a, **k):
for i in f(*a, **k):
if i[1]: return i
return func

@getfirst
def func():
var1 = something()
var2 = something_else('this')
yield "first try", var1.hobgle(var2)
var3 = last_resort(var1)
yield "second try", var3.wiglat(var2)
yield "default value", "Even that did not work."

Disclaimer: Untested, but you should get the idea.

Thomas