concatenation and recursion - python

#Calculates to the index position of a fib number.
def f3(n):
if n < 2:
return n
return f3(n-2) + f3(n-1)
The function only accepts one argument, yet two are being sent in the return, yet, it works! What's happening here?
If I return f3(n-3), the function breaks down. What effect does the concatenation have?

Addition results in a single value.
>>> 1 + 2
3
>>> [1] + [2]
[1, 2]

Python evaluates the expression f3(n-2) + f3(n-1) before returning it, so its actually returning the value of them combined. The same is the case for f3(n-2), its first evaluating n-2 and then passing it as a value to f3().
The number of return arguments has nothing to do with the number of arguments a function takes as input.

The line f3(n-2) + f3(n-1) is returning only one value, the result of calculating f3 for the input n-2 and then adding that value to the result of calculating f3 for the input n-1
In Python, the mechanism for returning multiple values from a function is by packing them inside a tuple and then extracting them at the time of invoking the function (not the case in your question!) For example:
def multivalue(x, y)
return (x, y)
a, b = multivalue(5,10)
# here a holds 5, and b holds 10

Related

How to convert a decimal number to another system using recursive function?

I am writing a function in Python that takes a number 'n' and a base 'b' that will convert a decimal number to another base using recursive function.
This is what I have so far:
def convert_number(n, b):
if n >= 1:
convert_number(n // b)
print(n % b, end = "")
When I test the function with convert_number(15, 3) this is what i get:
TypeError: convert_number() missing 1 required positional argument: 'b'
Nevertheless, the function works if I use a default value for b.
Since I'm new to programming, I've no idea what that means and what to change.
Thanks in advance for help :)
You probably want to return the result of your recursive call, and you need to make sure that you call the function correctly (it expects an n and b argument).
Generally in a recursive function you first handle the "base case" (the one where the input is small enough to not require recursion), and then you divide the input into one part that you can handle now and one part that needs to be handled by another (recursive) call to the function.
In this function, the base case is n < b (i.e. it's a single digit number), and for the recursive case we can use divmod to get the next digit and the remainder of the number that needs to be converted.
>>> def convert_number(n, b):
... if n < b:
... return str(n)
... n, digit = divmod(n, b)
... return convert_number(n, b) + str(digit)
...
>>> convert_number(10, 2)
'1010'

Understanding the code behind a gridtraveller

I found a basic code in python to find the numbers of paths you can take in a (m,n) grid if you can only go either down or right.
def gridtraveller(m,n):
if m == 0 or n == 0:
return 0
elif m == 1 or n == 1:
return 1
return gridtraveller(m-1,n) + gridtraveller(m,n-1)
But I dont understand why is this working for two thing:
What does def something (m,n) do ?
And why does here we return the definition ? ( I do understand why we return
m-1 and n-1 , but I don't understant the concepte of a def returning a def)
Thanks to you and sorry english is not my first language.
In Python the def keyword is simply used to define a function, in this case it's the function gridtraveller(m,n). What you're seeing with that last return statement is actually a function returning the value of another function. In this case it's returning the value of another call to gridtraveller, but with different parameter values; this is called recursion. An important part of recursion is having appropriate base cases, or return values that won't end in another recursive call(i.e. the return 0 or return 1 you see).
It can be easier to understand by simply stepping through a few iterations of the recursive calls. If your first function call starts with m = 2 and n = 1, the first call will end with return gridtraveller(1,1) + gridtraveller(2,0). The first call in that statement will then return 1 since either m or n are 1 and the second returns 0 since n = 0 here giving a total result of 1. If larger values of m and n are used it will obviously result in a higher number since more calls to gridtraver(m,n) will happen.

How to get minimum odd number using functions from list

I'm trying to get the minimum odd number using python. I used lambda, loops and other methods to get minimum odd number but i was not able to get that using functions. here is my code
z= [1,8,-4,-9]
def min_odd(x):
for i in x:
if (i%2!=0):
return min(i)
y = min_odd(z)
print (y)
Can some please tell me what i was missing here.
The min() function expects an iterable like a list which it will then yield the smallest element from.
E.g. min([1,0,3]) gives 0.
So if you want to use it, you must create a list (or other iterable) of the odd numbers that you can then pass into it:
def min_odd(x):
odds = []
for i in x:
if i % 2 != 0:
odds.append(i)
return min(odds)
note that we could also use a list-comprehension:
def min_odd(x):
return min([i for i in x if i % 2 != 0])
which both work.
An alternative method would be to store the current minimum odd value in a variable and update this variable if we come across a smaller odd value:
def min_odd(x):
min_v = float('inf')
for i in x:
if i % 2 != 0 and i < min_v:
min_v = i
return min_v
Try:
min([val for val in z if val % 2 != 0])
It seems your code logics are wrong. First off, you seem to have an indentation error in the return statement. Second off, the min() function requires a collection of items (like an array for example) or a series of arguments to determine the minimum in that series. You can try multiple things.
Use another variable to store a temporary minimum. Replace it every time you find a smaller odd value ( for every i in x... if the value is odd and is smaller than the previous odd value, replace it) and have it started with the first odd number you can find.
Take all the odd numbers and add them to another array on which you will apply the min function.
Hope this proves useful!
You could pass a generator into the min() function:
def min_odd(iterable):
return min(i for i in iterable if i % 2)
I didn't write i % 2 != 0 because any odd number will return 1 which has a Boolean value of True.
I added a parameter to the function that takes the iterable so it can be used for any iterable passed in.
min operates on an iterable. i is not an iterable in your code; it's the last element of the list.
You can achieve what you want with a filter, though:
min(filter(lambda e: e%2 != 0, x))

Generating unique Pythagorean triplets using this algorithm

def pyg(n):
n=int(n)
for i in range(1,n):
a=(2*i)+1
b=(2*i)*(i+1)
c=(2*i)*(i+1)+1
return(a,b,c)
When i try to run this on Shell using pyg(100) I only get output (3, 4, 5).
What might be the problem all the triplets are not generating.
As many others pointed out, when the return statement executes, your function will finish, and will not continue looping. However, you have options for returning multiple values from a single function. For example aggregating your values in a list and return that, or to use the yield keyword instead of return. The yield keyword will make your function a generator function, which returns an iterable generator object with all your expected elements.
I advise you to split your code into separate functions, so you have the original formula as a function of i, and a generator function which will return the elements for 1 <= i < n. Note that you can collect the elements of a generator to a list by supplying it to the list constructor.
def pyg(i):
a = (2*i) + 1
b = (2*i) * (i+1)
c = (2*i) * (i+1) + 1
return (a,b,c)
def pygs(n):
for i in range(1, n):
yield pyg(i)
print(list(pygs(10))) # prints the first 9 Pythagorean triplet as a list of tuples
The return sentence. Change it for a yield. If you want to test it, you could:
>>> pygs = pyg(100)
>>> next(pygs)
(3, 4, 5)
>>> next(pygs)
.
.
.
Your function produces only one pair, because return interrupts function execution. You could use yield keyword, as suggested by #jgomo3, or map function:
def generate_triplet(n):
a=(2*n)+1
b=(2*n)*(n+1)
c=(2*n)*(n+1)+1
return(a,b,c)
def pyg(n):
return map(generate_triplet, range(1, int(n))

Return Statements in Recursion

So I have a fairly decent understanding of the concept of recursion, but some implementations really trip me up. Take for instance this simple fibonacci function:
def fib(x):
if x == 0 or x == 1:
return 1
else:
return fib(x-1) + fib(x-2)
I get that this breaks up the fibonacci calculation into smaller more manageable chunks. But how exactly does it come to the end result? What exactly is return returning during the recursive cases? It seems like it is just returning a call to a function that will continue to call the function until it returns 1 -- but it never seems to do any really calculations/operations. Contrast this with the classic factorial function:
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n)
Here, the function is clearly operating on n, a defined integer, each time, whereas the fibonacci function only ever operates on the function itself until 1 is returned.
Finally, things get even weirder when we bring something like the Merge Sort algorithm into play; namely this chunk of code:
middle = int(len(L)/2)
left = sort(L[:middle], lt)
right = sort(L[middle:], lt)
print(left, right)
return merge(left, right, lt)
left and right seem to be recursively calling sort, yet the print statements seem to indicate that merge is working on every recursive call. So is each recursive call somehow "saved" and then operated on when merge is finally invoked on the return? I'm confusing myself more and more by the second.... I feel like I'm on the verge of a strong understanding of recursion, but my understanding of what exactly return does for recursive calls is standing in my way.
Not understanding how recursive functions work is quite common, but it really indicates that you just don't understand how functions and returning works, because recursive functions work exactly the same as ordinary functions.
print 4
This works because the print statement knows how to print values. It is given the value 4, and prints it.
print 3 + 1
The print statement doesn't understand how to print 3 + 1. 3 + 1 is not a value, it's an expression. Fortunately print doesn't need to know how to print an expression, because it never sees it. Python passes values to things, not expressions. So what Python does is evaluate the expression when the code is executed. In this case, that results in the value 4 being produced. Then the value 4 is given to the print statement, which happily prints it.
def f(x):
return x + 1
print f(3)
This is very similar to the above. f(3) is an expression, not a value. print can't do anything with it. Python has to evaluate the expression to produce a value to give to print. It does that by going and looking up the name f, which fortunately finds the function object created by the def statement, and calling the function with the argument 3.
This results the function's body being executed, with x bound to 3. As in the case with print, the return statement can't do anything with the expression x + 1, so Python evaluates that expression to try to find a value. x + 1 with x bound to 3 produces the value 4, which is then returned.
Returning a value from a function makes the evaluation of the function-call expression become that value. So, back out in print f(3), Python has successfully evaluated the expression f(3) to the value 4. Which print can then print.
def f(x):
return x + 2
def g(y):
return f(y * 2)
print g(1)
Here again, g(2) is an expression not a value, so it needs to be evaluated. Evaluating g(2) leads us to f(y * 2) with y bound to 1. y * 2 isn't a value, so we can't call f on it; we'll have to evaluate that first, which produces the value 2. We can then call f on 2, which returns x + 2 with x bound to 2. x + 2 evaluates to the value 4, which is returned from f and becomes the value of the expression f(y * 2) inside g. This finally gives a value for g to return, so the expression g(1) is evaluated to the value 4, which is then printed.
Note that when drilling down to evaluate f(2) Python still "remembered" that it was already in the middle of evaluating g(1), and it comes back to the right place once it knows what f(2) evaluates to.
That's it. That's all there is. You don't need to understand anything special about recursive functions. return makes the expression that called this particular invocation of the function become the value that was given to return. The immediate expression, not some higher-level expression that called a function that called a function that called a function. The innermost one. It doesn't matter whether the intermediate function-calls happen to be to the same function as this one or not. There's no way for return to even know whether this function was invoked recursively or not, let alone behave differently in the two cases. return always always always returns its value to the direct caller of this function, whatever it is. It never never never "skips" any of those steps and returns the value to a caller further out (such as the outermost caller of a recursive function).
But to help you see that this works, lets trace through the evaluation of fib(3) in more detail.
fib(3):
3 is not equal to 0 or equal to 1
need to evaluate fib(3 - 1) + fib(3 - 2)
3 - 1 is 2
fib(2):
2 is not equal to 0 or equal to 1
need to evaluate fib(2 - 1) + fib(2 - 2)
2 - 1 is 1
fib(1):
1 is equal to 0 or equal to 1
return 1
fib(1) is 1
2 - 2 is 0
fib(0):
0 is equal to 0 or equal to 1
return 1
fib(0) is 1
so fib(2 - 1) + fib(2 - 2) is 1 + 1
fib(2) is 2
3 - 2 is 1
fib(1):
1 is equal to 0 or equal to 1
return 1
fib(1) is 1
so fib(3 - 1) + fib(3 - 2) is 2 + 1
fib(3) is 3
More succinctly, fib(3) returns fib(2) + fib(1). fib(1) returns 1, but fib(3) returns that plus the result of fib(2). fib(2) returns fib(1) + fib(0); both of those return 1, so adding them together gives fib(2) the result of 2. Coming back to fib(3), which was fib(2) + fib(1), we're now in a position to say that that is 2 + 1 which is 3.
The key point you were missing was that while fib(0) or fib(1) returns 1, those 1s form part of the expressions that higher level calls are adding up.
Try this exercise:
What's the value of fib(0)? What's the value of fib(1)? Let's write those down.
fib(0) == 1
fib(1) == 1
We know this because these are "base cases": it matches the first case in the fib definition.
Ok, let's bump it up. What's the value of fib(2)? We can look at the definition of the function, and it's going to be:
fib(2) == fib(1) + fib(0)
We know what the value of fib(1) and fib(0) will be: both of those will do a little work, and then give us an answer. So we know fib(2) will eventually give us a value.
Ok, bump it up. What's the value of fib(3)? We can look at the definition, and it's going to be:
fib(3) == fib(2) + fib(1)
and we already know that fib(2) and fib(1) will eventually compute numbers for us. fib(2) will do a little more work than fib(1), but they'll both eventually bottom out to give us numbers that we can add.
Go for small cases first, and see that when you bump up the size of the problem that the subproblems are things that we'll know how to handle.
If you've gone through a standard high-school math class, you will have seen something similar to this already: mathematicians use what's called "mathematical induction", which is the same idea as the recursion we programmers use as a tool.
You need to understand mathematical induction to really grasp the concept. Once it is understood recursion is simply straightforward. Consider a simple function ,
def fun(a):
if a == 0: return a
else return a + 10
what does the return statement do here? It simply returns a+10. Why is this easy to understand? Of course, one reason is that it doesn't have recursion.;) Why is the return statement so easy to understand is that it has a and 10 available when it is called.
Now, consider a simple sum of n numbers program using recursion. Now, one important thing before coding a recursion is that you must understand how mathematically it is supposed to work. In the case of sum of n numbers we know that if sum of n-1 numbers is known we could return that sum + n. Now what if do not know that sum. Well, we find sum of n-2 terms and add n-1 to it.
So, sumofN(n) = n + sum(n-1).
Now, comes the terminating part. We know that this cant go on indefinitely. Because sumofN(0) = 0
so,
sumofN(n) = 0, if n = 0,
n + sumofN(n-1) , otherwise
In code this would mean,
def sumofN(n):
if n == 0: return 0
return n + sumofN(n-1)
Here suppose we call sumofN(10). It returns 10 + sumofN(9). We have 10 with us. What about the other term. It is the return value of some other function. So what we do is we wait till that function returns. Here, since the function being called is nothing but itself, it waits till sumofN(9) returns. And when we reach 9 + sumofN(8) it waits till sumofN(8) returns.
What actually happens is
10 + sumofN(9) , which is
10 + 9 + sumofN(8), which is
10 + 9 + 8 + sumofN(7) .....
and finally when sumofN(0) returns we have,
10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0 = 55
This concept is all that is needed to understand recursion. :).
Now, what about mergesort?
mergesort(someArray) = { l = mergesort the left part of array,
r = mergesort the right part of the array,
merge(l and r)
}
Until the left part is available to be returned, it goes on calling mergesort on the "leftest" arrays. Once we have that, we find the right array which indeed finds the "leftest" array. Once we have a left and right we merge them.
One thing about recursion is that it is so damn easy once you look at it from the right perspective and that right perspective is called mathematical induction

Categories

Resources