Initialize parameter in recursive function in Python - python

I wrote down simple algorithm for checking if Mersenne number is prime:
def is_prime_mers(result, step, modulo):
if result != 0:
if step == 0:
return False
result = result ** 2 - 2
if result >= modulo:
result %= modulo
return is_prime_mers(result, step - 1, modulo)
return True
Generally I don't need to give result parameter when script calls this function however I need it for recursive calls.
So only result need to be initialised for this function with value of 4
I can write some initializing function like:
def is_prime_mers_init(step):
is_prime_mers(4, step, count_mersenne(step))
But maybe there is some python/general programming pattern to do that in first function?
Edit: For all curious ones :)
This is function what implements Lucas-Lehmer test and checks if given Mersenne number is prime http://en.wikipedia.org/wiki/Lucas%E2%80%93Lehmer_primality_test - however I read only mathematic implementation - so this is purely my code solution.
step is number of recursive calls
count_mersenne(step) gives value of some Mersenne number: 2 ** step - 1 however I use some check in count_mersenne(step) because searching for prime Mersenne numbers can be limited to prime step values.

You can assign them dummy default values and then you can decide whether to change them or not, like this
def is_prime_mers(step, result = None, modulo = None):
if result is None:
result = 4 # Default value
if modulo is None:
modulo = count_mersenne(step) # Default value
Or in one liners
def is_prime_mers(step, result = None, modulo = None):
result = 4 if result is None else result
modulo = count_mersenne(step) if modulo is None else modulo

Related

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.

recursive function to sum of first odd numbers python

I'm trying to convert below code to recursive function but seems i'm quite confusing how could i write below in recursive function. could help me to give some thoughts?
Basically, what I'm generating below is the sum of the first n odd numbers.
def sum_odd_n(n):
total=0
j=2*n-1
i=1
if i>j:
return 1
else:
total =((j+1)/2)**2
i+=2
return total
> >>> sum_odd_n(5)
> 25.0
> >>> sum_odd_n(4)
> 16.0
> >>> sum_odd_n(1)
> 1.0
This smells somewhat like homework so I'm going to offer some advice instead of a solution.
Recursion is about expressing a problem in terms of itself.
Suppose you know the sum of the odd numbers from N to N - 2.
Can you write the total sum in terms of this sum and the function itself (or a related helper function)?
Recursive functions have at least one base case and at least one recursive call. Here are some hints:
def f(n):
# Base case - for which
# n do we already know the answer
# and can return it without
# more function calls? (Clearly,
# this must also terminate any
# recursive sequence.)
if n == ???:
return ???
# Otherwise, lets say we know the answer
# to f(n - 1) and assign it to
# the variable, 'rest'
rest = f(n - 1)
# What do we need to do with 'rest'
# to return the complete result
return rest + ???
Fill out the question marks and you'll have the answer.
Try:
def sum_of_odd(n):
if n>0:
x=(n*2)-1
return x+sum_of_odd(n-1)
else:
return 0
The answer of this:
sum_of_odd(5)
will be:
25
Try :
def sum_odd_n(n):
if n>0:
if n==1:
return 1
else:
return 2*n-1 + sum_odd_n(n-1)

Python: base case of a recursive function

Currently I'm experimenting a little bit with recursive functions in Python. I've read some things on the internet about them and I also built some simple functioning recursive functions myself. Although, I'm still not sure how to use the base case.
I know that a well-designed recursive function satisfies the following rules:
There is a base case.
The recursive steps work towards the base case.
The solutions of the subproblems provide a solution for the original problem.
Now I want to come down to the question that I have: Is it allowed to make up a base case from multiple statements?
In other words is the base case of the following self written script, valid?
def checkstring(n, string):
if len(string) == 1:
if string == n:
return 1
else:
return 0
if string[-1:] == n:
return 1 + checkstring(n, string[0:len(string) - 1])
else:
return checkstring(n, string[0:len(string) - 1])
print(checkstring('l', 'hello'))
Yes, of course it is: the only requirement on the base case is that it does not call the function recursively. Apart from that it can do anything it wants.
That is absolutely fine and valid function. Just remember that for any scenario that you can call a recursion function from, there should be a base case reachable by recursion flow.
For example, take a look at the following (stupid) recursive function:
def f(n):
if n == 0:
return True
return f(n - 2)
This function will never reach its base case (n == 0) if it was called for odd number, like 5. You want to avoid scenarios like that and think about all possible base cases the function can get to (in the example above, that would be 0 and 1). So you would do something like
def f(n):
if n == 0:
return True
if n == 1:
return False
if n < 0:
return f(-n)
return f(n - 2)
Now, that is correct function (with several ifs that checks if number is even).
Also note that your function will be quite slow. The reason for it is that Python string slices are slow and work for O(n) where n is length of sliced string. Thus, it is recommended to try non-recursive solution so that you can not re-slice string each time.
Also note that sometimes the function do not have strictly base case. For example, consider following brute-force function that prints all existing combinations of 4 digits:
def brute_force(a, current_digit):
if current_digit == 4:
# This means that we already chosen all 4 digits and
# we can just print the result
print a
else:
# Try to put each digit on the current_digit place and launch
# recursively
for i in range(10):
a[current_digit] = i
brute_force(a, current_digit + 1)
a = [0] * 4
brute_force(a, 0)
Here, because function does not return anything but just considers different options, we do not have a base case.
In simple terms Yes, as long as it does not require the need to call the function recursively to arrive at the base case. Everything else is allowed.

Python Fibonacci sequence error

this was one of the problems I was assigned in MyProgrammingLab. I've attempted to answer this problem over 45 times, but can't get it right.
Any help will be appreciated
Question:
In the following sequence, each number (except the first two) is the sum of the previous two numbers: 0, 1, 1, 2, 3, 5, 8, 13, .... This sequence is known as the Fibonacci sequence.
We speak of the i'th element of the sequence (starting at 0)-- thus the 0th element is 0, the 1st element is 1, the 2nd element is 1, the 3rd element is 2 and so on. Given the positive integer n, associate the nth value of the fibonacci sequence with the variable result. For example, if n is associated with the value 8 then result would be associated with 21.
My work:
def fib(n):
if n <= 1:
result == n
elif n >= 1:
result = fib(n-1)+fib(n-2)
else:
return result
It's because in all of your cases, you assign the result but don't return it.
So, for example, when fib(1) is called, Python returns None because you never told it to return result in that case. The same thing happens for, say, fib(45).
To correct this, just return result always. (This is a good idea no matter what type of program you are writing - functions should always have an explicit return value).
def fib(n):
if n <= 1:
result = n
elif n > 1:
result = fib(n-1)+fib(n-2)
return result # always return result!
Things to Know
You should be aware that this implementation of the Fibonacci sequence is the least efficient one out there. If you can ditch the recursive calls altogether and just use a while loop to calculate fib(n) - or, if you want recursion, store previously computed values of fib(n) instead of forcing it to compute all the way to fib(n) - you will have a much more efficient implementation.
Your code contained numerous issues, such as
Assigning without returning, which we've already discussed.
Using == instead of =. The first checks if the left and right hand side are equal, and returns True or False. The second actually assigns the value of the right hand side to the variable on the left hand side. Don't confuse checking for equality with assignment.
Using the same base case twice but telling Python to do something different in both cases. This is such a bad idea that I feel jonrsharpe in the comments is justified in saying "Seriously?". The reason for this is because doing this makes no sense and makes it hard to predict behaviour. The whole point of an if-else statement is to do different things in different cases.
Edit based on examples provided by OP. Indentation should only be four spaces, not eight. This is more of a stylistic issue than anything else, but it is the standard.
def fib(n):
if n < 2:
return n
else:
return fib(n-1)+fib(n-2)
You can essentially reduce it to this. You could even leave out the else and say:
def fib(n):
if n < 2:
return n
return fib(n-1)+fib(n-2)
but you said you need to have an else-case for whatever reason.
I wrote this one for my assignment. I know it's a little indirect, but it works and that's what's important :)
n = int(input("Insert a number: "))
i = 0
fib_list = [1, 1, 0]
for i in range (0,2):
if n == 0:
result = fib_list[2]
elif n <= 2:
result = fib_list[0]
for i in range (2,n):
result = fib_list[0] + fib_list[1]
fib_list.insert(0, result)
i += 1
result = fib_list[0]
By the way, you don't need to define an input to use in the myprogramminglab question.
I added the input version here because I used it in my tests.

Python does not follow order of PEMDAS?

I am programming a catalan number generator for homework, and I am doing a recursive program in pytohon.
The program:
def catalan(n):
if n == 0:
c_f = 1
else:
c_f = ((4*n-2)/(n+1))*catalan(n-1)
return c_f
print catalan(10)
returns 5832, which is the wrong answer, but
def catalan(n):
if n == 0:
c_f = 1
else:
c_f = (4*n-2)*catalan(n-1)/(n+1)
return c_f
print catalan(10)
gives me 16796, which is the correct answer.
So does python not follow PEMDAS?
Just like PEMDAS, python evaluates expressions from left to right. It evaluates (4*n-2)/(n+1), stores it (call the result X), and then computes X/catalan(n-1).
The problem is, what is the value of X? (4*n-2)/(n+1) is not an integer for all values of n, but if you're passing in a value of n that is a python int you're performing integer division. The result is that the fractional part of the computation is discarded, and your computation goes off the rails.
The second iteration works because of a property of the catalan function is that the (4*n-2)*catalan(n-1) expression will be a multiple of n-1. This way, you leave the (potentially destructive) division to the end of the expression, and the mathematical properties of you computation save you.

Categories

Resources