understanding the logic behind len()

This is the place for queries that don't fit in any of the other categories.

understanding the logic behind len()

Postby jean » Sun Oct 27, 2013 6:39 am

Hi

I am new to coding and I have been given an example of a function similar to the built in function len().



I do understand

def fct(s) :
if not s : return 0
return 1 + fct(s[1:])


However I am having a hard time understanding the logic of the one below which is the equivalent for what I see.

def fct(s) : return s and 1 + fct(s[1:]) or 0 #I do not understabd the "return s" part


could someone explain that to me?

Many thanks
Last edited by micseydel on Sun Oct 27, 2013 7:43 am, edited 1 time in total.
Reason: Locked op.
jean
 
Posts: 3
Joined: Sun Oct 27, 2013 6:30 am

Re: understanding the logic behind len()

Postby simongcx » Sun Oct 27, 2013 8:02 am

Try this:

Code: Select all
def myfunct(inputx):
    return True and inputx

print myfunct(5)


You'll see the True is not returned.

s is only True if it has items. Otherwise the 0 is returned.
simongcx
 
Posts: 2
Joined: Sat Oct 26, 2013 12:41 pm

Re: understanding the logic behind len()

Postby micseydel » Sun Oct 27, 2013 8:20 am

I think it's an uglier way to write
Code: Select all
return 1 + fct(s[1:]) if s else 0
Join the #python-forum IRC channel on irc.freenode.net!
User avatar
micseydel
 
Posts: 1115
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA

Re: understanding the logic behind len()

Postby jean » Sun Oct 27, 2013 9:58 am

Hi, Thank you for your adices, this will be useful.

However my real concern here is that I want to understand the logic behind this coding:

def fct(s) : return s and 1 + fct(s[1:]) or 0

someone could explain what happens step by step "behind the scene" with that function?

Many thanks
jean
 
Posts: 3
Joined: Sun Oct 27, 2013 6:30 am

Re: understanding the logic behind len()

Postby Somelauw » Sun Oct 27, 2013 6:13 pm

jean wrote:Hi, Thank you for your adices, this will be useful.

However my real concern here is that I want to understand the logic behind this coding:

def fct(s) : return s and 1 + fct(s[1:]) or 0

someone could explain what happens step by step "behind the scene" with that function?

Many thanks


It's pretty ugly code and you should probably read another book or follow another class.
"a and b" returns b when bool(a) is true and a when bool(a) is false
"a or b" returns a when bool(a) is true and b when bool(a) is false.

bool(a) is generally true when a is not empty or zero. It's defined differently on each datatype.

That means the code is equivalent to:
Code: Select all
def fct(s):
    if bool(s):
        # the if below never fails
        if bool(1 + fct[s[1:]]):
            return 1 + fct[s[1:]])
        else:
            return 0
    else:
        return 0
Join the #python-forum IRC channel on irc.freenode.net!
Somelauw
 
Posts: 68
Joined: Tue Feb 12, 2013 8:30 pm

Re: understanding the logic behind len()

Postby ochichinyezaboombwa » Mon Oct 28, 2013 10:05 pm

"
Code: Select all
some_condition and something or something_else
" is in fact a typical and well-known Python idiom.
It is analogous to C/C++ operator "?":
Code: Select all
condition ? answer1 : answer2;
a > c ? a : c; // returns the maximum of (a,c)


It works like this (in Python):
a) If some_condition is True (or a non-zero number or a non-empty string): the result is "something";
b) otherwise, it is yet_something_else.

For example:
Code: Select all
>>> s = "aaa"; print s and 18 or 99
18
>>> s = ""; print s and 18 or 99
99



So in your case it:
1) tests if s is empty;
2) if yes , it returns 0;
3) if not, it returns 1 + whatever is the result of fct for the s except its first character.

This effectively calculates the length of the string and teaches you recursion (fct calls itself with the slightly different argument several times).
ochichinyezaboombwa
 
Posts: 200
Joined: Tue Jun 04, 2013 7:53 pm

Re: understanding the logic behind len()

Postby jean » Mon Oct 28, 2013 11:37 pm

Thanks a lot ochichinyezaboombwa for your detailed answer. I am still trying to get my head around the logic of this line but it makes a little bit more sense now.
jean
 
Posts: 3
Joined: Sun Oct 27, 2013 6:30 am

Re: understanding the logic behind len()

Postby ochichinyezaboombwa » Tue Oct 29, 2013 3:27 am

Maybe let's try harder. The idiom
Code: Select all
condition and res1 or res2
works the way it works because of the way operators "and" and "or" work.

In operator "and", both its left part and its right part matter; both must become True to make the whole thing True.

For example:
Code: Select all
>>> True and True
True
>>> True and False
False
>>> False and "Whatever"
False


Now what's tricky about it is the following: the operator and starts with calculating its left part 1st, AND if its value is False it doesn't even bother to look at the 2nd (right) part. Indeed, why bother? The condition "Both must be True" is already broken, so the result of the whole expression is already known. Python (and most languages) make a smart decision here to avoid doing totally unnecessary calculations.
To illustrate:

Code: Select all
>>> def foo(x):
...     print "I am in foo, my arg is ", x
...
>>> foo(5)
I am in foo, my arg is  5
>>>
>>> False and foo(5)
False
Notice how in the 2nd call ("False and foo(5)") foo() was NOT called at all!!!

The operator "or" works the opposite way: if its left side is not True it might still be OK: the right part gets calculated and the overall result of "or" depends on it.

Now, to confuse you a little more: there is the VALUE of operators and or or (as there is the value of any expression).
Namely, the value of operations like and or or is... what was calculated last. To illustrate (with the same foo() as above):
Code: Select all
>>> s = ""
>>> print repr(s and foo(5))
''
>>> s = "ABC"
>>> print repr(s and foo(5))
I am in foo, my arg is 5
None


I use repr() here because otherwise we wouldn't see anything after the 1st call: it prints the empty string s''; importantly, foo was not called. In a case s == "ABC", however, foo() does get called and what is printed as the overall result is whatever foo returns (and we know it returns nothing, or None).

Now I hope it should be clear what you should expect from the following and why:
Code: Select all
>>> s = ""
>>> print repr(s and "Foo" or "Bar")
>>> s = "ABC"
>>> print repr(s and "Foo" or "Bar")


And this is basically identical to your return statement.

Did it help at all?
ochichinyezaboombwa
 
Posts: 200
Joined: Tue Jun 04, 2013 7:53 pm


Return to General Coding Help

Who is online

Users browsing this forum: No registered users and 2 guests