[Tutor] Cannot Understand

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Fri Mar 10 20:54:40 CET 2006



On Fri, 10 Mar 2006, Edgar Antonio Rodriguez Velazco wrote:

> Could you please explain this code?.
>
> f = lambda n: n-1 + abs(n-1) and f(n-1)*n or 1

Hi Edgar,


This is terrible code.  *grin*

I know that this is the factorial function in disguise, but this is just
Wrong.  I don't think we should study this too seriously, just because the
code is deliberately trying to be obscure.


But if you really insist... let's break it down into pieces.  Let's slowly
transform it in phases:

##############################################
f = lambda n: n-1 + abs(n-1) and f(n-1)*n or 1
##############################################


First, let's convert this to a familiar definition without lambdas:

###########################################
def f(n):
    return n-1 + abs(n-1) and f(n-1)*n or 1
###########################################


Next, let's observe that AND and OR behave like this:

    x AND y --> if x:
                     return y
                else:
                     return x

    x OR y  --> if x:
                     return x
                else:
                     return y


(This is to a first rough approximation.  We're ignoring details, like the
fact that Python's if statement isn't an expression, and that we're
evaluating this more times than they deserve... *grin*):


Ok, let's apply this change to f(n).  Let's attack the AND first:

##############################
def f(n):
    if n-1 + abs(n-1):
        return f(n-1) * n or 1
    else:
        return n-1 + abs(n-1):
##############################


The expression n-1 + abs(n-1) is always a true value... except in the case
where n is zero.


So this is really saying is something much less profound than it looks:

##############################
def f(n):
    if n:
        return f(n-1) * n or 1
    else:
        return 0
##############################


Ok, let's attack the OR now:

##############################
def f(n):
    if n:
        if f(n-1) * n:
            return f(n-1) * n
        else:
            return 1
    else:
        return 0
##############################


(... In retrospect, this really is a recursive definition that's a broken
factorial function.  f(0) evaluates to zero, but it really should be 1.)

If you're familiar with the recursive factorial function, the version of
f(n) above now will be pretty recognizable now.  If not, then I think I
have to stop anyway, because then we're going into "what's recursion?",
which is a whole another topic.  *grin*


If you have any questions, please feel free to ask.  I hope this helps!



More information about the Tutor mailing list