Python 3 Recursion - Maximum Depth Exceeded - python

I'm writing a basic recursion function that takes an integer, n, and returns the sum of the first n reciprocals. Inputting 2 should result in 1.5, and inputting 0 should return 0.
sum_to(2) = (1 + 1/2) = 1.5
Here's what I have:
def sum_to(n):
if n>0:
return sum_to(1+1/n) # Not sure if this is correct
return 0
But all I'm getting is a Maximum recursion depth exceeded. I know I could lists to solve this, but recursion is really intriguing and I want to find a solution using it.

From the question, it seems that you want to compute
\sum_{i=1}^{n} 1/i
If the input is 0, then returns 0.
Remember that in a recursive function, you need to define a base case and an inductive clause.
In your question, the inductive clause is:
1.0 / i + sum_of_reciprocals(i-1)
while the base case can be set to 0 when i=0.
Given this formulation, the function with an example looks like:
def sum_to(n):
if n > 0:
return sum_to(n-1) + 1.0 / n
else:
return 0
if __name__ == '__main__':
print(sum_to(3))
and the result is 1.83333333333.
For more information about recursive functions, you can start from the related wikipedia page.

Trace through it to see if you ever reach your end condition:
(PS: at the time I wrote this the question's code was return 1 + sum_to(1/n))
sum_to(2):
n is 2, which is > 0
call sum_to(1/2)
n is .5, which is > 0
call sum_to(1/.5)
n is 2, which is > 0
call sum_to(1/2)
...
Your function never returns. The result would be infinite if you had infinite time and space to finish the calculation, since there is no end to the algorithm.
For your example, just write it this way:
def sum_to(n):
return 1 + 1/n
What is the expected result when n > 2? That will determine how to approach organizing working code.

Related

Query regarding Bit Counting (Python)

I tried to solve this Kata problem
Write a function that takes an integer as input, and returns the number of bits that are equal to one in the binary representation of that number. You can guarantee that input is non-negative.
Example: The binary representation of 1234 is 10011010010, so the function should return 5 in this case.
But the problem is my code gives the correct answers right for the first time around but when
it is run for 2nd time onward it gives wrong answers only. I think it has to do sth with how my code is recursive. Please help me figure it out.
for example when i run count_bits(24) it gives the output 2 which is correct but when i run the same function again it would give 4 and then 6 and so on . I dont know what's wrong with this
My code.
dec_num = []
def count_bits(n):
def DecimalToBinary(n):
if n >= 1:
DecimalToBinary(n // 2)
dec_num.append( n % 2)
return dec_num
dec = DecimalToBinary(n)
return dec.count(1)
There is no need to create a list of digits if all you need is their sum. When possible, avoid creating mutable state in a recursive solution:
def count_bits(n):
if n > 0:
return n % 2 + count_bits(n // 2)
else:
return 0
That's a pretty natural translation of the obvious algorithm:
The sum of the bits in a number is the last bit plus the sum of the bits in the rest of the number.
Sometimes it's convenient to accumulate a result, which is best done by adding an accumulator argument. In some languages, that can limit stack usage, although not in Python which doesn't condense tail calls. All the same, some might find this more readable:
def count_bits(n, accum = 0):
if n > 0:
return count_bits(n // 2, accum + n % 2)
else:
return accum
In Python, a generator is a more natural control structure:
def each_bit(n):
while n > 0:
yield n % 2
n //= 2
def count_bits(n):
return sum(each_bit(n))
Of course, there are lots more ways to solve this problem.
That is because dec_num is outside the method, so it's reused at every call, put it inside
def count_bits(n):
dec_num = []
def DecimalToBinary(n):
if n >= 1:
DecimalToBinary(n // 2)
dec_num.append(n % 2)
return dec_num
dec = DecimalToBinary(n)
return dec.count(1)

Create an algorithm whose recurrence is T(n) = T(n/3) + T(n/4) + O(n^2)

How do I go about problems like this one: T(n) = T(n/3) + T(n/4) + O(n^2)
I am able to use two for loops which will give me the O(n^2), right?
To interpret the equation, read it in English as: "the running time for an input of size n equals the running time for an input of size n/3, plus the running time for an input of size n/4, plus a time proportional to n^2".
Writing code that runs in time proportional to n^2 is possible using nested loops, for example, though it's simpler to write a single loop like for i in range(n ** 2): ....
Writing code that runs in time equal to the time it takes for the algorithm with an input of size n/3 or n/4 is even easier - just call the algorithm recursively with an input of that size. (Don't forget a base case for the recursion to terminate on.)
Putting it together, the code could look something like this:
def nonsense_algorithm(n):
if n <= 0:
print('base case')
else:
nonsense_algorithm(n // 3)
nonsense_algorithm(n // 4)
for i in range(n ** 2):
print('constant amount of text')
I've used integer division (rounding down) because I don't think it makes sense otherwise.
Here, we would use for and range(start, stop, steps), maybe with a simple to understand algorithm, similar to:
def algorithm_n2(n: int) -> int:
"""Returns an integer for a O(N2) addition algorithm
:n: must be a positive integer
"""
if n < 1:
return False
output = 0
for i in range(n):
for j in range(n):
output += n * 2
for i in range(0, n, 3):
output += n / 3
for i in range(0, n, 4):
output += n / 4
return int(output)
# Test
if __name__ == "__main__":
print(algorithm_n2(24))
Using print() inside a method is not a best practice.
Output
27748

why maximum recursion limit error is caused when code(1) is executed and no error when code(2) is executed

So here is the 2 python codes of Fibonacci series using recursive function. I wanted to know the difference between these code and why code(1) is not working, and code(2) works without any error?
This is not working and shows error of maximum recursion limit:
def f(n):
return f(n-1) + f(n-2)
n=8
f(n)
whereas this works:
def f(n):
if n == 0:
return 0
if n == 1:
return 1
else:
return f(n-1) + f(n-2)
f(4)
Your first code has no way of stopping. It does not have the base cases for n == 0 or n == 1, so it will continue infinitely downwards with negative numbers.
If you add:
if n <= 1:
return 0
you're golden. (allthough it is a very inefficient implementation of fibonacci).
Why is it inefficient, well because each subtree are calculated many times over. f(8) calls f(7) and f(6), but f(7) also call f(6), so you get an exponential recursive tree. Your running time will be O(2^n). This is really bad, normally you will not be able to calculate fib for n even as low as 50.
You can do better if you include memoization:
from functools import lru_cache
#lru_cache(maxsize=None)
def fib2(n):
if n <= 1:
return n
else:
return fib2(n-1) + fib2(n-2)
This will remember if you have called f(n) before and return the answer you did last time. The issue now is that you need to remember previous called numbers, so while your running time has decreased to O(n), your space requirement is now O(n) too.
You can improve on this again, by abandoning recursive functions all together and go
def fib3(n):
if n == 0:
return 0
f1 = 0
f2 = 1
for i in range(n-1):
f1,f2 = f2, f1+f2
return f2
This is better, since you are only remembering two numbers at any time.

Returning the digit count of a number using recursion

I'm trying to return the count of digits in a number using recursion like this:
DigitCount(3456) → 4.
The code that I have without using recursion works fine, which is:
def DigitCount(n)
return len(str(n))
But when I try using recursion in this way:
def DigitCount(n):
return len(str(DigitCount(n)))
I get an error message saying 'RecursionError: maximum recursion depth exceeded'
The problem with your recursive function is that you didn't specify a base case to end the recursion, producing an infinite loop that ends with a stack overflow.
When writing recursive procedures, you have to think how to make the problem smaller at each call (in this case, dividing by 10 does the trick) until you reach a point where the problem is so simple, that you already know the answer - for instance, a number less than 10 has a single digit. Try this:
def DigitCount(n):
if n < 10:
return 1
else:
return 1 + DigitCount(n / 10) # use n // 10 in Python 3.x
It works as expected, as long as n is greater than or equal to zero:
DigitCount(0)
=> 1
DigitCount(234)
=> 3
What about something like:
def DigitCount(n):
if n<10: return 1
return 1 + DigitCount(n//10)
The idea is:
a number smaller than 10 has length 1
a number greater than 10 has length 1 + length(n//10); for instance 456 has length 1 + length(45).
It can be done using strings also.
def digitCount(n):
if len(str(n)) == 1:
return 1
else:
return 1 + digitCount(str(n)[1:])
It's a bit dirty, and very inefficient but works.

Why is my recursive function erring?

I need to write a recursive function, dec2base(n, b), that returns a list of base b digits in the positive integer n. For example.
dec2base(120, 10) => [1,2,0] (1 * 10**2 + 2 * 10**1 + 0 * 10**0)
Currently I have.
def dec2base(n, b):
if n < 10:
return [n]
else:
return dec2base(n, b) + [n%b]
But when I run the program, it returns an infinite loop error. Any ideas?
You are not decrementing the value of n at any point in your method, so if you start with any value of n >=10, the loop never ends.
Another observation - the logic of "if n < 10 return [n]" seems not to make sense if b is not equal to 10. For instance, 9 < 10, but I'm assuming the value of dec2base(9,2) would not be [9]. It would be [1,0,0,1].
Okay, in any recursive function, there has to be some function that goes to zero in order to have something to stop. In this case, what you want is to really model the way you7 do it by hand:
divide by the radix (the base)
put the remainder in as a digite
recur using the same base, but the other part of the division. (The quotient.)
That is, if you are finding the hex value of 1000, you take
dec2base(1000,16):
if first parameter == 0, return, you're done
1000 mod 16 (=8) -> save the 8
dec2base(62, 16) -> recursion step
Now, obviously every time you make the recusion step, the first parameter is smaller, and if you think about it, that eventually must go to 0. So eventually it will terminate.
Here's a real simple version in Python:
result = ""
def dec2base(n,b):
global result
if n <= 0: return
result = str(n % b) + result # why am I prepending it?
dec2base( n // b, b)
if __name__ == '__main__':
dec2base(1000,8)
print result
Now, if the base is anything > 9 (say 16) you'll need to take care of translating values from 10 to 15 into alpha a-f, and this is purposefully not very elegant because I wanted it to lay out just like the example.
There's only a couple of tiny mistakes in your solution.
def dec2base(n, b):
if n < b: # so it will work for bases other than 10
return [n]
else:
return dec2base(n//b, b) + [n%b] # you're just missing "//b" here
You can simplify it slightly like this
def dec2base(n, b):
if not n:
return []
return dec2base(n//b, b) + [n%b]
Your calling dec2base(n, b) to infinity. If you call
dec2base(20, b)
Your function will continue to execute the 2nd branch of your if/else statement. You need to pass a reduced value to your recursive function call so that eventually, n < 10 will evaluate to True.

Categories

Resources