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.

>>> True and TrueTrue>>> True and FalseFalse>>> 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:

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):

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: